T-SQL группировка наборов информации - PullRequest
0 голосов
/ 22 ноября 2011

У меня есть проблема, которую мои ограниченные знания SQL мешают мне понять.

Первая проблема:

У меня есть база данных, по которой мне нужно запустить отчет, она содержит конфигурации прав пользователей.В отчете должен быть представлен отдельный список этих конфигураций и их количество.

Таким образом, строка в моей БД выглядит так:

USER_ID SALE_ITEM_ID    SALE_ITEM_NAME  PRODUCT_NAME    CURRENT_LINK_NUM    PRICE_SHEET_ID
37715     547             CultFREE    CultPlus         0                561 

строка выше представляет собой одну строкуконфигурация пользователя, для каждого идентификатора пользователя может быть 1-5 таких строк.Таким образом, определение конфигурации - это несколько строк данных с общим идентификатором пользователя с переменными атрибутами.

Мне нужно получить отдельный список этих конфигураций по всей таблице, оставив менятолько один набор конфигурации для каждого экземпляра, где> 1 имеет эту конфигурацию и количество экземпляров этой конфигурации.

Надеюсь, это понятно?

Есть идеи?!?!

Я пробовал различные группы и союзы, а также функции групповых наборов безрезультатно.

Буду очень признателен, если кто-нибудь даст мне несколько указателей!

Ответы [ 2 ]

0 голосов
/ 22 ноября 2011

Какое больно ...

Хорошо, так что проблема:

  1. строка представляет собой настраиваемую строку
  2. пользователи могут быть связаны с более чем 1 строкконфигурация
  3. строки конфигурации, когда они сгруппированы вместе, образуют набор конфигурации
  4. мы хотим выяснить все отдельные наборы конфигурации
  5. мы хотим знать, какие пользователи их используют.1014 *

Решение (оно немного грязное, но идея есть, скопируйте и вставьте в SQL Management Studio) ...

-- ok so i imported the data to a table named SampleData ... 
-- 1. import the data 
-- 2. add a new column
-- 3. select all the values of the config in to the new column (Configuration_id)
--UPDATE [dbo].[SampleData]
--SET [Configuration_ID] = SALE_ITEM_ID + SALE_ITEM_NAME + [PRODUCT_NAME] + [CURRENT_LINK_NUM] + [PRICE_SHEET_ID] + [Configuration_ID]

-- 4. i then selected just the distinct values of those and found 6 distinct Configuration_id's 
--SELECT DISTINCT [Configuration_ID] FROM [dbo].[SampleData]

-- 5. to make them a bit easier to read and work with i gave them int values instead 
--    for me it was easy to do this manually but you might wanna do some trickery here to autonumber them or something 
--    basic idea is to run the step 4 statement but select into a new table then add a new primary key column and set identity spec on it
--    that will generate u a bunch of incremental numbers for your config id's so u can then do something like ...
--UPDATE [dbo].[SampleData] sd
--SET Configuration_ID = (SELECT ID FROM TempConfigTable WHERE Config_ID = sd.Configuration_ID)

-- at this point you have all your existing rows with a unique ident for the values combined in each row.
-- so for example in my dataset i have several rows where only the user_id has changed but all look like this ...
--SALE_ITEM_ID  SALE_ITEM_NAME  PRODUCT_NAME    CURRENT_LINK_NUM    PRICE_SHEET_ID  Configuration_ID
--54101 TravelFREE  TravelPlus  0   56101   1

-- now you have a config id you can start to work on building sets up ...
-- each user is now matched with 1 or more config id 
-- 6. we use a CTE (common table expression) to link the possibles (keeps the join small) ...
--WITH Temp (ConfigID)
--AS
--(
--  SELECT DISTINCT SD.Configuration_Id --SD2.Configuration_Id, SD3.Configuration_Id, SD4.Configuration_Id, SD5.Configuration_Id, 
--  FROM [dbo].[SampleData] SD
--)
-- this extracts all the possible combinations using the CTE
-- on the basis of what you told me, max rows per user is 6, in the result set i have i only have 5 distinct configs
-- meaning i gain nothing by doing a 6th join.
-- cross joins basically give you every combination of unique values from the 2 tables but we joined back on the same table 
-- so its every possible combination of Temp + Temp (ConfigID + ConfigID) ... per cross join so with 5 joins its every combination of 
-- Temp + Temp + Temp + Temp + Temp .. good job temp only has 1 column with 5 values in it
-- 7. uncomment both this and the CTE above ... need to use them together
--SELECT DISTINCT T.ConfigID C1, T2.ConfigID C2, T3.ConfigID C3, T4.ConfigID C4, T5.ConfigID C5
--INTO [SETS]
--FROM Temp T
--CROSS JOIN Temp T2
--CROSS JOIN Temp T3
--CROSS JOIN Temp T4
--CROSS JOIN Temp T5

-- notice the INTO clause ... this dumps me out a new [SETS] table in my db
-- if i go add a primary key to this and set its ident spec i now have unique set id's 
-- for each row in the table.
--SELECT *
--FROM [dbo].[SETS]

-- now here's where it gets interesting ... row 1 defines a set as being config id 1 and nothing else 
-- row 2 defines set 2 as being config 1 and config 2 and nothing else ... and so on ...
-- the problem here of course is that 1,2,1,1,1 is technically the same set as 1,1,1,2,1 from our point of view
-- ok lets assign a set to each userid ...
-- 8. first we pull the distinct id's out ...
--SELECT DISTINCT USER_ID usr, null SetID 
--INTO UserSets
--FROM SampleData 

-- now we need to do bit a of operating on these that's a bit much for a single update or select so ...
-- 9. process findings in a loop
DECLARE @currentUser int
DECLARE @set int
-- while theres a userid not linked to a set
WHILE EXISTS(@currentUser = SELECT TOP 1 usr FROM UserSets WHERE SetId IS NULL)
BEGIN
    -- figure out a set to link it to
    SET @set = (
        SELECT TOP 1 ID 
        FROM [SETS]
        -- shouldn't really do this ... basically need to refactor in to a table variable then compare to that
        -- that way the table lookup on ur main data is only 1 per User_id
        WHERE C1 IN (SELECT DISTINCT Configuration_id FROM SampleData WHERE USER_ID = @currentUser)
        AND C2 IN (SELECT DISTINCT Configuration_id FROM SampleData WHERE USER_ID = @currentUser)
        AND C3 IN (SELECT DISTINCT Configuration_id FROM SampleData WHERE USER_ID = @currentUser)
        AND C4 IN (SELECT DISTINCT Configuration_id FROM SampleData WHERE USER_ID = @currentUser)
        AND C5 IN (SELECT DISTINCT Configuration_id FROM SampleData WHERE USER_ID = @currentUser)
    )
    -- hopefully that worked 
    IF(@set IS NOT NULL)
    BEGIN 
        -- tell the usersets table 
        UPDATE UserSets SET SetId = @set WHERE usr = @currentUser
        set @set = null
    END
    ELSE -- something went wrong ... set to 0 to prevent endless loop but any userid linked to set 0 is a problem u need to look at
        UPDATE UserSets SET SetId = 0 WHERE usr = @currentUser
    -- and round we go again ... until we are done
END
0 голосов
/ 22 ноября 2011
SELECT
USER_ID,
SALE_ITEM_ID, ETC...,
COUNT(*) WhateverYouWantToNameCount

FROM TableNAme
GROUP BY USER_ID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...