Muszę dołączyć do 2 stołów w relacji wiele:wiele. Kod 1 pozycji może zawierać wiele kodów materiałów i na odwrót.

Podczas wykonywania zapytania SQL wyniki wyświetlają wszystkie wiersze, które pasują z obu stron, w następujący sposób:

enter image description here

Ale nie chcę mieć zduplikowanych wartości.

Moje pożądane wyniki wyglądają następująco:

enter image description here

Jak uzyskać taki wynik?

Moje zapytanie SQL to:

SELECT DISTINCT
    x._PROCESS_INST_NO,  
    x._GOODS_CD,
    x._QTY,
    y._GOODS_CD,
    Y._QTY
FROM 
    [TBL_PROC_PM] x
FULL OUTER JOIN 
    (SELECT  
         t._PROCESS_INST_NO,
         t._GOODS_CD,
         t._QTY
     FROM 
         [TBL_PROC_PMS] t) y ON y._PROCESS_INST_NO = x._PROCESS_INST_NO
WHERE 
    y._PROCESS_INST_NO IN ('631886', '635312')  

2 tabele SQL:

SELECT [_PROCESS_INST_NO]     
      ,[_GOODS_CD]     
      ,[_QTY]    
  FROM [TBL_PROC_PM]
   where _PROCESS_INST_NO IN ('631886', '635312')  

enter image description here

SELECT [_PROCESS_INST_NO]     
      ,[_GOODS_CD]     
      ,[_QTY]    
  FROM [TBL_PROC_PMS]
   where _PROCESS_INST_NO IN ('631886', '635312') 

enter image description here

0
Cát Tường Vy 24 listopad 2018, 13:22

1 odpowiedź

Najlepsza odpowiedź

Czy chcesz, aby puste wartości były zwracane w komórkach dla kolejnych zduplikowanych wartości w kolumnach, czy chcesz zwinąć zduplikowane wyniki? Jeśli to drugie, możesz spróbować tego:

SELECT
    x._PROCESS_INST_NO, 
    x._GOODS_CD, 
    SUM(x._QTY) AS [SUM_PM_QTY],
    STUFF ((
        SELECT ', ' + _GOODS_CD
        FROM @TBL_PROC_PMS t2
        WHERE t2._PROCESS_INST_NO = x._PROCESS_INST_NO
        FOR XML PATH('')), 1, 1, ''
    ) AS [PMS_GOODS_CDS],
    SUM(y._QTY) AS [SUM_PMS_QTY]
FROM @TBL_PROC_PM AS x
JOIN @TBL_PROC_PMS AS y ON y._PROCESS_INST_NO = x._PROCESS_INST_NO
GROUP BY x._PROCESS_INST_NO, x._GOODS_CD;

To usunie duplikaty, grupując je. Pogrupowałem też/połączyłem wartości cd towarów pms za pomocą składni STUFF ... FOR XML PATH.

enter image description here

Jeśli z drugiej strony chcesz mieć puste wartości, może coś takiego może Ci pomóc:

WITH cte AS --(PM_PROCESS_INST_NO, PM_GOODS_CD, PM_QTY, PMS_GOODS_CD, PMS_QTY)
(
    SELECT 
        o._PROCESS_INST_NO AS PM_PROCESS_INST_NO,       
        o._GOODS_CD AS PM_GOODS_CD,
        o._QTY AS PM_QTY,
        f._GOODS_CD AS PMS_GOODS_CD,
        f._QTY AS PMS_QTY,
        ROW_NUMBER() OVER (PARTITION BY o._PROCESS_INST_NO ORDER BY o._PROCESS_INST_NO) AS GRP_PROCESS_INST_NO,
        ROW_NUMBER() OVER (PARTITION BY o._GOODS_CD ORDER BY o._GOODS_CD) AS GRP_GOODS_CD,
        ROW_NUMBER() OVER (PARTITION BY o._QTY ORDER BY o._QTY) AS GRP_QTY
    FROM   @TBL_PROC_PM o
    JOIN @TBL_PROC_PMS f ON f._PROCESS_INST_NO = o._PROCESS_INST_NO 
)
SELECT
    CASE WHEN GRP_PROCESS_INST_NO = 1 THEN cte.PM_PROCESS_INST_NO ELSE '' END AS PM_PROCESS_INST_NO,
    CASE WHEN GRP_GOODS_CD = 1 THEN cte.PM_GOODS_CD ELSE '' END AS PM_GOODS_CD,
    CASE WHEN GRP_QTY = 1 THEN cte.PM_QTY ELSE '' END AS PM_QTY,
    cte.PMS_GOODS_CD,
    cte.PMS_QTY
FROM cte;

To zwróci puste wartości (biorąc pod uwagę, że typy danych obsługują puste wartości)

enter image description here

1
Carlo Bos 25 listopad 2018, 05:10