一个简单的问题。我有一个数据库,我试图从3行的表中获取所有匹配项。
RECEIPT | ORIGINAL_RECEIPT | EXCHANGED_RECEIPT
51651651 | 1245678 | 58453874
我正在使用的查询现在可以完美且快速地运行
select distinct RECEIPT from RECEIPT_DATA WHERE ORIGINAL_RECEIPT = '1245678'
UNION
select distinct ORIGINAL_RECEIPT from RECEIPT_DATA WHERE ORIGINAL_RECEIPT = '1245678'
UNION
select distinct EXCHANGED_RECEIPT from RECEIPT_DATA WHERE ORIGINAL_RECEIPT = '1245678'
order by RECEIPT asc
然后应返回
51651651
1245678
58453874
很明显,我的行有很多,并且ORIGINAL_RECEIPT可能有很多交换,而且全部。
就像我说的那样,这很完美,但是我很好奇还有什么其他方法可以解决?有没有不搜索数据库3次? 我听说案例可以解决这个问题吗?也许还有交叉申请?
答案 0 :(得分:1)
您标记了SSMS,因此,我将使用APPLY
代替UNION
:
SELECT DISTINCT RDD.RECEIPTS
FROM RECEIPT_DATA RD CROSS APPLY
( VALUES (RECEIPT), (ORIGINAL_RECEIPT), (EXCHANGED_RECEIPT)
) RDD(RECEIPTS)
WHERE RD.ORIGINAL_RECEIPT = 1245678;
DISTINCT
实际上是不必要的,因为您使用了UNION
,因此它将为您删除重复项。
但是,为了获得更好的性能,您将需要在RECEIPT_DATA(ORIGINAL_RECEIPT)
上建立索引。
答案 1 :(得分:1)
我建议:
CREATE DEFINER=`root`@`localhost` PROCEDURE `select_medicoes`(
whereCondicao varchar(200))
BEGIN
DECLARE ID_novo int;
DECLARE ID_Variavel int;
DECLARE ID_Cultura int;
DECLARE NumMed int;
DECLARE DataHoraMed date;
DECLARE ValorMed int;
DECLARE done INT DEFAULT FALSE;
DECLARE curs_medicoeslog cursor for
(SELECT *
FROM `dba`.medicoes
WHERE `whereCondicao`);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SELECT `whereCondicao`;
OPEN curs_medicoeslog;
read_loop: LOOP
FETCH curs_medicoeslog INTO ID_Variavel, ID_Cultura, NumMed, DataHoraMed, ValorMed;
INSERT INTO log_medicoes (IDVariavel, IDCultura, NumMedicao, DataHoraMedicao, ValorMedicao, Utilizador, `Data`, Operacao)
VALUES (ID_Variavel, ID_Cultura, NumMed, DataHoraMed, ValorMed, current_user(), now(), 'S');
IF done THEN
LEAVE read_loop;
END IF;
END LOOP;
CLOSE curs_medicoeslog;
END
而且,您希望在select DISTINCT (CASE WHEN n.n = 1 THEN RECEIPT
WHEN n.n = 2 THEN ORIGINAL_RECEIPT
WHEN n.n = 3 THEN EXCHANGED_RECEIPT
END
)
from RECEIPT_DATA CROSS JOIN
(SELECT 1 as n UNION ALL SELECT 2 UNION ALL SELECT 3) n
WHERE ORIGINAL_RECEIPT = '1245678';
上建立索引。
您的查询版本正在执行大量重复消除操作-既在每个子查询中,也使用RECEIPT_DATA(ORIGINAL_RECEIPT)
。这简化了重复消除。
但是,最大的问题可能是UNION
上缺少索引。
此版本可在MySQL和SQL Server中使用。但是,在SQL Server中,我将使用ORIGINAL_RECEIPT
来表达它。