Как сделать внешнее соединение со столбцом на основе количества? - PullRequest
1 голос
/ 22 сентября 2010

Что может быть эффективным способом решения следующей проблемы в SQL 2008?

Первые две - это входные таблицы, с помощью которых мне нужно заполнить 3-ю (таблица DataOut)

В основном, WDATAбудет иметь ноль или более строк, соответствующих каждой строке таблицы DataIn.Мне нужно заполнить таблицу DataOut всеми строками, в том числе ни одной совпадающей и множественной совпадающей, и заполнить столбец состояния, различающий одну соответствующую строку в WDATA, Нет строки в WDATA или ровно одну строку в WDATA.

DataIn
QID  RID  DOB
-------------
1    1    01/01/1980
1    2    03/01/1981
1    3    01/02/1991



WDATA(key is QID, RID,PID)
QID  RID  PID
---------------
1    1    101
1    1    102
1    3    204



DataOut
QID  RID  PID  status
-----------------------
1    1    101  ”multiple match”
1    1    102  ”multiple match”
1    2    null ”no match”
1    3    204  ”single match”

Ответы [ 3 ]

2 голосов
/ 22 сентября 2010

Как насчет этого запроса здесь ??

SELECT
    di.QID, di.RID, w.PID,
    CASE (SELECT COUNT(*) FROM WDATA w2 WHERE di.QID = w2.QID AND di.RID = w2.RID)
        WHEN 0 THEN 'no match'
        WHEN 1 THEN 'single match'
        ELSE 'multiple match'
    END AS 'Status'
FROM
    DataIn di 
LEFT OUTER JOIN 
    WDATA w ON di.QID = w.QID AND di.RID = w.RID

Для меня это выдает:

QID  RID  PID   Status
 1    1   101   multiple match
 1    1   102   multiple match
 1    2   NULL  no match
 1    3   204   single match

Это то, что вы ищете ??

0 голосов
/ 22 сентября 2010

Это выглядит нормально, я думаю, что это можно улучшить, хотя.

DECLARE @DataIn TABLE
(
    QID INT NOT NULL,
    RID INT NOT NULL,
    DOB DATE NOT NULL
)
INSERT INTO @DataIn
VALUES
(1,1,'01/01/1980'),
(1,2,'03/01/1981'),
(1,3,'01/02/1991')

DECLARE @WDATA TABLE
(
    QID INT NOT NULL,
    RID INT NOT NULL,
    PID INT NOT NULL        
)
INSERT INTO @WDATA
VALUES
(1,1,101),
(1,1,102),
(1,3,204)

;WITH OuterCTE(QID, RID, PID) AS
(
SELECT 
    ISNULL(D.QID, W.QID) AS QID,
    ISNULL(D.RID, W.RID) AS RID,    
    W.PID
FROM @DataIn AS D FULL OUTER JOIN @WDATA AS W ON W.RID = D.RID AND W.QID = D.QID
)

SELECT
    CTE.QID,
    CTE.RID,
    CTE.PID,
    CASE 
        WHEN COUNT(W.PID) = 0 THEN 'no match'
        WHEN COUNT(W.PID) = 1 THEN 'single match'
        ELSE 'multiple match'
    END
FROM
    OuterCTE AS CTE
    LEFT JOIN @WDATA AS W 
    ON CTE.QID = W.QID 
    AND CTE.RID = W.RID
GROUP BY
    CTE.QID,
    CTE.RID,
    CTE.PID
0 голосов
/ 22 сентября 2010

Попробуйте это:

SELECT di.QID,di.RID,wd.PID, 
CASE 
   WHEN  wd.PID is null THEN 'no match'
   WHEN COUNT(di.QID) = 1 THEN 'single match'
   WHEN COUNT(di.QID) > 1 THEN 'multiple match'
END
FROM DataIn as di
LEFT JOIN WDATA as wd
ON di.QID = wd.QID AND di.RID = wd.RID
GROUP BY di.QID,di.RID,wd.PID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...