|
SQL: JOIN с "ленивым" условием | ☑ | ||
---|---|---|---|---|
0
Asmody
13.11.15
✎
16:24
|
Такая задачка:
Пусть есть таблица A с полями A1 и A2 типа integer и A_DATA типа varchar, и таблица B с полями B_ID типа integer и B_DATA типа varchar. Требуется в запросе получить строки (A_DATA, B_DATA), соединив таблицы по A1=B_ID, а если такой строки нет, то по A2=B_ID (аналог "ленивого" ИЛИ). |
|||
1
User_Agronom
13.11.15
✎
16:28
|
выбор А.А_дата, Б.Б_Дата из А кАК А
левое соединение Б КАК Б По A1=B_ID где не Б.Б_Дата есть нулл объединить все другая таблица |
|||
2
Asmody
13.11.15
✎
16:31
|
(1)
"левое соединение Б КАК Б По A1=B_ID где не Б.Б_Дата есть нулл" — это просто внутреннее соединение |
|||
3
ViSo76
13.11.15
✎
16:34
|
И что так не прокатывает?
выбор А.А_дата, Б.Б_Дата из А кАК А левое соединение Б КАК Б По A1=B_ID Или A2=B_ID |
|||
4
Asmody
13.11.15
✎
16:36
|
(3) Так выберутся строки и с А1, и с А2. Но А2 нужно искать тогда и только тогда, когда А1 не найдено.
|
|||
5
PR третий
13.11.15
✎
16:38
|
(0) Делаешь ЛС А и Б, а потом еще раз ЛС с Б, уже зная в первом соединении, есть запись в Б или нет.
|
|||
6
butterbean
13.11.15
✎
16:43
|
(4)
ВЫБОР А.А_дата, Б.Б_Дата из А кАК А левое соединение Б КАК Б ПО ВЫБОР КОГДА A1=B_ID ТОГДА ИСТИНА ИНАЧЕ A2=B_ID КОНЕЦ |
|||
7
ViSo76
13.11.15
✎
16:46
|
выбор
А.А_дата, Б.Б_Дата из А кАК А левое соединение Б КАК Б По A1=B_ID Или ( A1<>B_ID A2=B_ID ) |
|||
8
ViSo76
13.11.15
✎
16:47
|
(7) Точнее
выбор А.А_дата, Б.Б_Дата из А кАК А левое соединение Б КАК Б По A1=B_ID Или ( A1<>B_ID И A2=B_ID ) |
|||
9
ViSo76
13.11.15
✎
16:48
|
(4) Приз в студию
|
|||
10
Asmody
13.11.15
✎
16:51
|
(6) (8) не пойдет
|
|||
11
Garykom
гуру
13.11.15
✎
16:52
|
(0) уже было не так давно полностью тоже самое но без А и Б
|
|||
12
Asmody
13.11.15
✎
16:54
|
A:
(1, 2, A) (3, 4, B) B: (1, a) (2, b) (4, c) в результате должно быть: (A, a) (B, c) |
|||
13
Asmody
13.11.15
✎
16:55
|
Даже вот так:
A: (1, 2, A) (3, 4, B) (5, 6, С) B: (1, a) (2, b) (4, c) в результате должно быть: (A, a) (B, c) |
|||
14
PR третий
13.11.15
✎
16:55
|
(5) Хотя лучше А ЛС Б ЛС Б
Первое ЛС по A1=B_ID, второе по A2=B_ID. А в поле ВЫБОР. |
|||
15
Ненавижу 1С
гуру
13.11.15
✎
16:59
|
выбрать
A_DATA, CASE WHEN NOT Б1.B_ID IS NULL THEN Б1.B_DATA ELSE Б2.B_DATA END из А левое соединение Б как Б1 по А.A1=Б1.B_ID левое соединение Б как Б2 по А.A2=Б2.B_ID |
|||
16
Asmody
13.11.15
✎
17:01
|
(15) останутся будут строки из А, для которых нет B_ID
|
|||
17
ViSo76
13.11.15
✎
17:02
|
(10) Ты уверен что (8) не прокатит?
|
|||
18
Ненавижу 1С
гуру
13.11.15
✎
17:02
|
+(16) ДОбавь
ГДЕ НЕ(Б1.B_ID IS NULL И Б2.B_ID IS NULL) |
|||
19
Asmody
13.11.15
✎
17:11
|
(17) вот тут можно потренироваться
http://kripken.github.io/sql.js/GUI/ заготовка примера DROP TABLE IF EXISTS A; DROP TABLE IF EXISTS B; CREATE TABLE A (a1 integer, a2 integer, a_data varchar); CREATE TABLE B (b_id integer, b_data varchar); INSERT INTO A VALUES (1,2,'A'); INSERT INTO A VALUES (3,4,'B'); INSERT INTO A VALUES (5,6,'C'); INSERT INTO B VALUES (1,'a'); INSERT INTO B VALUES (2,'b'); INSERT INTO B VALUES (4,'c'); |
|||
20
Ненавижу 1С
гуру
13.11.15
✎
17:17
|
вот
SELECT A_DATA, CASE WHEN NOT B1.B_ID IS NULL THEN B1.B_DATA ELSE B2.B_DATA END as b_data FROM A LEFT JOIN B AS B1 ON A.A1=B1.B_ID LEFT JOIN B AS B2 ON A.A2=B2.B_ID WHERE NOT(B1.B_ID IS NULL AND B2.B_ID IS NULL) |
|||
21
Asmody
13.11.15
✎
17:18
|
У меня вышло так:
SELECT a_data, CASE WHEN NOT b1.b_data IS NULL THEN b1.b_data ELSE b2.b_data END as b_data FROM A LEFT JOIN B as B1 ON a1=b1.b_id INNER JOIN B as B2 ON a2=b2.b_id |
|||
22
Ненавижу 1С
гуру
13.11.15
✎
17:22
|
(21) а если a2=b2.b_id не выполнится строка пропадет
|
|||
23
Asmody
13.11.15
✎
17:22
|
да, точно
|
|||
24
sda553
15.11.15
✎
01:39
|
select isnull(a_1.adata,a_2.adata).b.data
from b left join a a_1 on a_1.a1=b.id left join a a_2 on a_2.a2=b.id |
|||
25
Asmody
16.11.15
✎
09:34
|
(24) Не, возвращает 2 строки, когда а1 и а2 находятся.
|
|||
26
Ненавижу 1С
гуру
16.11.15
✎
10:20
|
я выиграл в (20). Где мой приз?
|
|||
27
Гёдза
16.11.15
✎
10:25
|
(25) А разве отношение не 1 к 1?
|
|||
28
Ёпрст
16.11.15
✎
10:28
|
SELECT
A_DATA, coalesce(B1.B_DATA,B2.B_DATA) as b_data FROM A LEFT JOIN B AS B1 ON A.A1=B1.B_ID LEFT JOIN B AS B2 ON A.A2=B2.B_ID WHERE NOT(coalesce(B1.B_DATA,B2.B_DATA)IS NULL) |
|||
29
elCust
16.11.15
✎
10:50
|
SELECT * FROM (SELECT a.a_data, b_data From A Left join B as B ON a.a1=b.b_id UNION ALL SELECT a.a_data, b_data From A Left join B as B ON a.a2=b.b_id) AS tem WHERE b_data NOT NULL
|
|||
30
Ёпрст
16.11.15
✎
11:10
|
(29) лишняя строка возвращается (проверка в (19) )
|
|||
31
rabbidX
16.11.15
✎
11:40
|
(13) (А,b) нет в результате из-за того, что есть (А,а)?
|
|||
32
Asmody
16.11.15
✎
12:02
|
(31) ага
|
|||
33
sda553
18.11.15
✎
07:10
|
(25) неа, одну
но может задвоится, но данные вернык. можно для устранения задвоения добавить distinct или group |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |