根据联合中使用的列获取正确的记录
Get correct records based on column from union which are used in join
此 select 在包中用作 left outer join
:
SELECT * (SELECT db1.id, db2.value, db1.discount, 2 AS attr_number FROM database1 db1
JOIN database2 db2 ON db2.db1_id = db1.id
WHERE db2.value = 1
UNION
SELECT db1.id, db4.value, db1.discount, 1 AS attr_number FROM database1 db1
JOIN database4 db4 ON db4.db1_id = db1.id
WHERE db4.value = 1) WHERE id = 225
他 return给我发了这个记录:
|ID |VALUE |DISCOUNT |ATTR_NUMBER |
|-------------|------------------|------------------|------------------|
|225 |1 |50 |2 |
|225 |1 |50 |2 |
|225 |1 |40 |1 |
|225 |1 |40 |1 |
|225 |1 |40 |1 |
所以我需要考虑 attr_number
行并根据该字段获取记录。
如您所见,attr_number
行值只能是 1 或 2。
根据这个例子,记录存在两个值,在这种情况下我们只需要 return attr_number = 1
(因为它存在),所以这是一个他应该 [=38] 的例子=]:
|ID |VALUE |DISCOUNT |ATTR_NUMBER |
|-------------|------------------|------------------|------------------|
|225 |1 |40 |1 |
|225 |1 |40 |1 |
|225 |1 |40 |1 |
如您所见,他 "removed" 记录 attr_number = 2
和 returning 仅在 1 的位置。
在其他情况下,如果select不return记录where attr_number = 1
,他return所有其他记录,在这种情况下它会是attr_number = 2
。这是他在这种情况下应该 return 的示例:
|ID |VALUE |DISCOUNT |ATTR_NUMBER |
|-------------|------------------|------------------|------------------|
|225 |1 |50 |2 |
|225 |1 |50 |2 |
希望我的解释足够清楚。
创建 2 个 CTE
,每个联合查询一个,然后使用 NOT EXISTS
:
WITH
cte1 AS (
SELECT db1.id, db4.value, db1.discount, 1 AS attr_number
FROM database1 db1 JOIN database4 db4
ON db4.db1_id = db1.id
WHERE id = 225 AND value = 1
),
cte2 AS (
SELECT db1.id, db2.value, db1.discount, 2 AS attr_number
FROM database1 db1 JOIN database2 db2
ON db2.db1_id = db1.id
WHERE id = 225 db2.value = 1
)
SELECT * FROM cte1
UNION ALL
SELECT * FROM cte2
WHERE NOT EXISTS (SELECT 1 FROM cte1 WHERE attr_number = 1)
您可以使用 RANK
对结果进行排名,只保留最好的行(即 attr_number
较低的行)。
select db1.id, 1 as value, db1.discount, dbx.attr_number
from database1 db1
join
(
select db1_id, attr_number, rank() over (order by attr_number) as rn
from
(
select db1_id, 2 as attr_number from database2 db2 where value = 1
union all
select db1_id, 1 as attr_number from database4 db4 where value = 1
)
) dbx on dbx.db1_id = db1.id and dbx.rn = 1
where db1.id = 225;
此 select 在包中用作 left outer join
:
SELECT * (SELECT db1.id, db2.value, db1.discount, 2 AS attr_number FROM database1 db1
JOIN database2 db2 ON db2.db1_id = db1.id
WHERE db2.value = 1
UNION
SELECT db1.id, db4.value, db1.discount, 1 AS attr_number FROM database1 db1
JOIN database4 db4 ON db4.db1_id = db1.id
WHERE db4.value = 1) WHERE id = 225
他 return给我发了这个记录:
|ID |VALUE |DISCOUNT |ATTR_NUMBER |
|-------------|------------------|------------------|------------------|
|225 |1 |50 |2 |
|225 |1 |50 |2 |
|225 |1 |40 |1 |
|225 |1 |40 |1 |
|225 |1 |40 |1 |
所以我需要考虑 attr_number
行并根据该字段获取记录。
如您所见,attr_number
行值只能是 1 或 2。
根据这个例子,记录存在两个值,在这种情况下我们只需要 return attr_number = 1
(因为它存在),所以这是一个他应该 [=38] 的例子=]:
|ID |VALUE |DISCOUNT |ATTR_NUMBER |
|-------------|------------------|------------------|------------------|
|225 |1 |40 |1 |
|225 |1 |40 |1 |
|225 |1 |40 |1 |
如您所见,他 "removed" 记录 attr_number = 2
和 returning 仅在 1 的位置。
在其他情况下,如果select不return记录where attr_number = 1
,他return所有其他记录,在这种情况下它会是attr_number = 2
。这是他在这种情况下应该 return 的示例:
|ID |VALUE |DISCOUNT |ATTR_NUMBER |
|-------------|------------------|------------------|------------------|
|225 |1 |50 |2 |
|225 |1 |50 |2 |
希望我的解释足够清楚。
创建 2 个 CTE
,每个联合查询一个,然后使用 NOT EXISTS
:
WITH
cte1 AS (
SELECT db1.id, db4.value, db1.discount, 1 AS attr_number
FROM database1 db1 JOIN database4 db4
ON db4.db1_id = db1.id
WHERE id = 225 AND value = 1
),
cte2 AS (
SELECT db1.id, db2.value, db1.discount, 2 AS attr_number
FROM database1 db1 JOIN database2 db2
ON db2.db1_id = db1.id
WHERE id = 225 db2.value = 1
)
SELECT * FROM cte1
UNION ALL
SELECT * FROM cte2
WHERE NOT EXISTS (SELECT 1 FROM cte1 WHERE attr_number = 1)
您可以使用 RANK
对结果进行排名,只保留最好的行(即 attr_number
较低的行)。
select db1.id, 1 as value, db1.discount, dbx.attr_number
from database1 db1
join
(
select db1_id, attr_number, rank() over (order by attr_number) as rn
from
(
select db1_id, 2 as attr_number from database2 db2 where value = 1
union all
select db1_id, 1 as attr_number from database4 db4 where value = 1
)
) dbx on dbx.db1_id = db1.id and dbx.rn = 1
where db1.id = 225;