Интересно, возможен ли следующий примерный пример без использования промежуточных переменных и условного предложения.Выполнение соединения только в том случае, если счетчик больше одного
Рассмотрите промежуточный запрос, который может создать набор результатов, который не содержит ни строк, ни одной строки, ни нескольких строк. Большую часть времени он производит только одну строку, но когда несколько строк, нужно присоединить полученные строки к другой таблице, чтобы сократить ее до одной или без строк. После этого, если есть одна строка (в отличие от строк), нужно было бы возвращать несколько столбцов, созданных исходным промежуточным запросом.
У меня в голове что-то вроде следующего, но он, очевидно, не будет работать (несколько столбцов в случае коммутатора, нет соединения и т. Д.), Но, возможно, это иллюстрирует точку. Я хотел бы просто вернуть то, что в настоящее время находится в пункте SELECT
, в случае @@ROWCOUNT = 1
, или в случае, если оно больше, сделайте INNER JOIN
до Auxilliary
, который уменьшает x
до одной строки или без строк, а затем возвращает это. Я не хочу искать Main
более одного раза и Auxilliary
только тогда, когда x
здесь содержит несколько строк.
SELECT x.MainId, x.Data1, x.Data2, x.Data3,
CASE
WHEN @@ROWCOUNT IS NOT NULL AND @@ROWCOUNT = 1 THEN
1
WHEN @@ROWCOUNT IS NOT NULL AND @@ROWCOUNT > 1 THEN
-- Use here @id or MainId to join to Auxilliary and there
-- FilteringCondition = @filteringCondition to prune x to either
-- one or zero rows.
END
FROM
(
SELECT
MainId,
Data1,
Data2,
Data3
FROM Main
WHERE
MainId = @id
) AS x;
CREATE TABLE Main
(
-- This Id may introduce more than row, so it is joined to
-- Auxilliary for further pruning with the given conditions.
MainId INT,
Data1 NVARCHAR(MAX) NOT NULL,
Data2 NVARCHAR(MAX) NOT NULL,
Data3 NVARCHAR(MAX) NOT NULL,
AuxilliaryId INT NOT NULL
);
CREATE TABLE Auxilliary
(
AuxilliaryId INT IDENTITY(1, 1) PRIMARY KEY,
FilteringCondition NVARCHAR(1000) NOT NULL
);
Возможно ли это в одном запросе без временной переменной таблицы и условного? Без использования CTE?
Некоторые образцы данные будут
INSERT INTO Auxilliary(FilteringCondition)
VALUES
(N'SomeFilteringCondition1'),
(N'SomeFilteringCondition2'),
(N'SomeFilteringCondition3');
INSERT INTO Main(MainId, Data1, Data2, Data3, AuxilliaryId)
VALUES
(1, N'SomeMainData11', N'SomeMainData12', N'SomeMainData13', 1),
(1, N'SomeMainData21', N'SomeMainData22', N'SomeMainData23', 2),
(2, N'SomeMainData31', N'SomeMainData32', N'SomeMainData33', 3);
И пример запроса, который на самом деле ведет себя, как я хотел бы, чтобы вести себя с той оговоркой, что я хочу сделать только присоединиться, если запрос Main
непосредственно с данный идентификатор дает более одного результата.
DECLARE @id AS INT = 1;
DECLARE @filteringCondition AS NVARCHAR(1000) = N'SomeFilteringCondition1';
SELECT *
FROM
Main
INNER JOIN Auxilliary AS aux ON aux.AuxilliaryId = Main.AuxilliaryId
WHERE MainId = @id AND aux.FilteringCondition = @filteringCondition;
вы могли бы изменить этот вопрос и предоставить образец данные и желаемые результаты , Я уверен, что это можно сделать с помощью одного запроса, но трудно точно понять, что вы пытаетесь сделать. –
Несомненно!Я постараюсь сделать это скоро (достаточно)! – Veksi
@GordonLinoff Спасибо, что спросили! Я действительно заметил недостаток в моем вопросе также в том, что Id in Main не обязательно уникален. Дело в том, что у меня есть ситуация в существующей базе данных, которая, как мне кажется, я знаю, как ее решить, но я тоже пытаюсь воспитывать себя в этом процессе. Дело в том, что выполнение соединения в большинстве случаев не требуется и может быть довольно проблематичным из-за производительности. Тогда также возникает проблема с возвратом нескольких результатов в код (из-за изменений в приложении и больших данных). – Veksi