2014-02-03 5 views
1

У меня есть две таблицы: ItemCategories и элементы. ItemCategories перечисляет категории для элементов и содержит текстовые строки, зависящие от языка. Столбец CultureCode определяет, к какому языку принадлежит текст.Условные левые соединения

ItemCategories

ID Name   CultureCode 
1 Food   'en-us' 
2 Clothing  'en-us' 
3 Computers  'en-us' 
4 Books   'en-us' 
1 Essen   'de-de' 
2 Kleidung  'de-de' 
3 Rechner   'de-de' 
4 Bücher   'de-de' 

Предметы

ID CategoryID1 CategoryID2 
4 1   NULL 
5 NULL  2 
6 3   4 
7 NULL  NULL 

В таблице перечислены Элементы каждого элемента и значения под CategoryID1 и CategoryID2 относятся к полю ID в CategoryItems. Значения CategoryID1 и CategoryID2 могут быть как null, так и установлены в ID или только один из них установлен на значение ID.

Мне нужно создать SQL (T-SQL), который возвращает идентификатор из элементов вместе с его соответствующим именем из ItemCategories, когда для параметра CultureCode задан конкретный язык. Так что, если мой CultureCode установлен в «ан-нас», результаты должны быть:

ID CategoryID1 CategoryID2 CategoryName1 CategoryName2 
4 1   NULL   Food   Null 
5 NULL  2   null   Clothing 
6 3   4   Computers  Books 
7 NULL  NULL   null   null 

Это то, что я до сих пор:

Select I.* 
From Items I 
Left Join ItemCategories IC On (IC.ID = I.CategoryID1) Or (IC.ID = I.CategoryID2) 
where (IC.CultureCode = 'en-us') Or (IC.CultureCode is null) 

Но это не дает мне результаты, которые я хочу ,

+0

Что вы дадите? – Nathan

ответ

1

Похоже, вам нужно разделить ваши LEFT JOIN на две отдельные LEFT JOIN S:

SELECT I.ID, I.CategoryID1, I.CategoryID2, CategoryName1 = IC1.Name, CategoryName2 = IC2.Name 
    FROM Items I 
     LEFT JOIN ItemCategories IC1 ON IC1.ID = I.CategoryID1 AND IC1.CultureCode = 'en-us' 
     LEFT JOIN ItemCategories IC2 ON IC2.ID = I.CategoryID2 AND IC2.CultureCode = 'en-us'; 
+0

У меня, как правило, было два отдельных левых соединения, но я не понял, что вам нужно поместить CultureCode в его состав. Впервые я когда-либо видел размещение условной части (IC1.CultureCode = 'en-us') как часть фактического соединения. В основном я рассматривал это как часть предложения Where. Узнайте что-то новое каждый день. Бесконечно благодарен. – AndroidDev

+0

Да, я узнал, где я ошибся, спасибо! –

0

Попробуйте и дайте мне знать ваши результаты/комментарии.

CREATE TABLE ItemCategories 
(
ID INT 
,Name VARCHAR(50) 
,CultureCode VARCHAR(5) 

) 
GO 
INSERT INTO ItemCategories VALUES(1 ,'Food '  ,  'en-us') 
INSERT INTO ItemCategories VALUES(2 ,'Clothing' ,  'en-us') 
INSERT INTO ItemCategories VALUES(3 ,'Computers' ,  'en-us') 
INSERT INTO ItemCategories VALUES(4 ,'Books'  ,  'en-us') 
INSERT INTO ItemCategories VALUES(1 ,'Essen'  ,  'de-de') 
INSERT INTO ItemCategories VALUES(2 ,'Kleidung' ,  'de-de') 
INSERT INTO ItemCategories VALUES(3 ,'Rechner' , 'de-de') 
INSERT INTO ItemCategories VALUES(4 ,'Bücher ' ,  'de-de') 


CREATE TABLE Items 
(
ID INT 
,CategoryID1 INT 
,CategoryID2 INT 

) 
GO 

INSERT INTO Items VALUES (4 , 1  , NULL) 
INSERT INTO Items VALUES (5 , NULL , 2 ) 
INSERT INTO Items VALUES (6 , 3  , 4 ) 
INSERT INTO Items VALUES (7 , NULL , NULL) 

Select I.*,IC.Name,IT.Name 
From Items I 
    left join ItemCategories IC ON (IC.ID = I.CategoryID1) AND IC.CultureCode = 'en-us' 
    left join ItemCategories IT On (It.ID = I.CategoryID2) AND IT.CultureCode = 'en-us' 
+0

Это генерирует ошибку: Недопустимое имя столбца «Имя». – AndroidDev

+0

Теперь попробуйте обновить код. –

+0

Такая же ошибка. У вас не может быть IT.Name. Кроме того, не имеет смысла, почему вы повторяете IT.Name дважды в select. – AndroidDev

0

Вы можете сделать это двумя способами:

использования подзапросов:

Select 
    I.ID, 
    (SELECT TOP 1 ID FROM ItemCategories IC WHERE IC.ID=I.CategoryID1 AND IC.CultureCode = 'en-us') AS CategoryID1, 
    (SELECT TOP 1 ID FROM ItemCategories IC WHERE IC.ID=I.CategoryID2 AND IC.CultureCode = 'en-us') AS CategoryID2, 
    (SELECT TOP 1 Name FROM ItemCategories IC WHERE IC.ID=I.CategoryID1 AND IC.CultureCode = 'en-us') AS CategoryName1, 
    (SELECT TOP 1 Name FROM ItemCategories IC WHERE IC.ID=I.CategoryID2 AND IC.CultureCode = 'en-us') AS CategoryName2 
From Items I 

Или, разделите запрос на 2 соединения

SELECT DISTINCT I.*, IC1.Name AS CategoryName1, IC2.Name AS CategoryName2 
FROM Items I 
LEFT JOIN ItemCategories IC1 ON I.CategoryID1=IC1.ID 
LEFT JOIN ItemCategories IC2 ON I.CategoryID2=IC2.ID 
WHERE (IC1.CultureCode IS NULL OR IC1.CultureCode = 'en-us') AND (IC2.CultureCode IS NULL OR IC2.CultureCode = 'en-us'); 
Смежные вопросы