powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Проблема с подзапросом
12 сообщений из 12, страница 1 из 1
Проблема с подзапросом
    #32022038
Sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Недавно столкнулся с проблемой и пока непонятно как ее обойти.Вот суть:хочется иметь запрос типа:

SELECT A.Name, (SELECT A.Value WHERE A.PropertyID=1),....,(SELECT A.Value WHERE A.PropertyID=100)
FROM (SELECT A.Name,B.PropertyID,B.Value FROM Objects A INNER JOIN Properties B
ON A.ObjectID=B.ObjectID) A INNER JOIN Types B ON A.Name=B.Name

Но проблема в том что алиас A не виден в подзапросе для Value. Может быть кто-нибудь подскажет идею ?

На замечания о нормализации базы скажу что базу проектировал не я, а пользоваться приходится мне ...
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022045
MadDog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А Вы пробовали выполнять этот запрос? В подзапросах отсутствует from.
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022061
Фотография Александр Степанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Select
A.Name,
Property001.Value As Property001,
...
Property100.Value As Property100
From
Objects A
INNER JOIN Types B
ON A.Name=B.Name
LEFT JOIN Properties As Properties001
ON Properties001.ObjectID=A.ObjectID AND Properties001.PropertyID=1
...
LEFT JOIN Properties As Properties100
ON Properties100.ObjectID=A.ObjectID AND Properties100.PropertyID=100

Использование LEFT JOIN необходимо, если Вам ружно увидеть записи, для которых не все properties присутствуют в БД. Запрос не обещает быть быстрым, но это происходит всегда, когда таблицу надо "положить на бок"
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022063
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пожалуй 100 JOIN-ов действительно будут долго работать


SELECT a.name, c.*
FROM Objects a
INNER JOIN Types B ON A.Name=B.Name
LEFT OUTER JOIN
(SELECT objectid,
MAX(case propertyid when 1 then propertyname else NULL end) as propertyname001,
MAX(case propertyid when 2 then propertyname else NULL end) as propertyname002,
MAX(case propertyid when 3 then propertyname else NULL end) as propertyname003,
.....
MAX(case propertyid when 100 then propertyname else NULL end) as propertyname100,
FROM Properties
GROUP BY objectid
) AS c ON c.ObjectID = A.ObjectID
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022095
Sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
to Александров Степанов:

Для этого запроса критична именно скорость выполнения. Поэтому боюсь вариант с использованием большого числа LEFT JOIN не приемлем ...

to Glory:

Спасибо! Очень интересный вариант. Я думаю именно его я и выберу. У меня также есть свой вариант и вопрос по данной теме.
Если я сделаю некий view для выборки данных типа SELECT ObjectID,PropertyID,Value ...
а затем в запросе буду использовать сто подзапросов типа (SELECT Value FROM View1 WHERE PropertyID=N AND ObjectID=A.ObjectID) не будет ли его время в сто раз больше времени на выполнения запроса во view и вообще насколько полно кэшируются данные после таких запросов?
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022127
Владимир Смирнов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня сейчас подобная проблема. Только с некоторыми осложнениями.
Таблица содержит 8 битовых полей F1..F8 и поле S, где значения от 1 до 10.

CREATE TABLE Kart (ID int identity(1,1),
F1 bit,
F2 bit,
F3 bit,
F4 bit,
F5 bit,
F6 bit,
F7 bit,
F8 bit,
St tinyint)
-- Заполнение
SET NOCOUNT ON
INSERT INTO Kart SELECT 0,1,1,0,1,0,0,1,9
INSERT INTO Kart SELECT 0,1,0,0,0,1,0,0,2
INSERT INTO Kart SELECT 1,0,1,0,0,0,0,1,4
INSERT INTO Kart SELECT 0,0,0,0,0,0,1,0,1
INSERT INTO Kart SELECT 1,1,0,0,0,0,0,1,9
INSERT INTO Kart SELECT 0,0,0,0,1,0,0,0,2
INSERT INTO Kart SELECT 0,0,0,0,0,0,0,1,3
INSERT INTO Kart SELECT 0,0,1,1,1,0,0,0,9
INSERT INTO Kart SELECT 0,0,0,1,1,0,0,0,4

Задача в том, что нужно получить отчёт, где столбцы - S1..S10, строки F1..F8, а значения - кол-во карт с включенным F. То есть вида:

S1 S2 S3 S4 S5 S6 S7 S8 S9 S10
F1 0 0 0 1 0 0 0 0 1 0
F2 ...
.
F8 0 0 1 1 0 0 0 0 2 0

Кол-во записей в таблице - 20К..200К, но для отчёта отбирается по доп. условию меньше до ~10К.
Я пока опробую вариант с дополнительной таблицей с полями F1..F8 и 8 записями:
1,0,0,0,0,0,0,0
0,1,0,0,0,0,0,0
0,0,1,0,0,0,0,0
0,0,0,1,0,0,0,0
0,0,0,0,1,0,0,0
0,0,0,0,0,1,0,0
0,0,0,0,0,0,1,0
0,0,0,0,0,0,0,1
Связать по полям F, а по S считать столбцы.

Может у кого есть другие идеи? Подскажите.
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022156
Фотография Александр Степанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Glory:

Да, Ваш вариант имеет более низкую цену, причем отрыв тем существеннее, чем больше пропертей надо достать.
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022165
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Владимир Смирнов
Если нужно так "переворачивать" таблицу, то может быть лучше поменять строки и столбцы в структуре ?

У меня получается такой вариант(как базовая идея). Таблица #temp2 была использована только для проверки промежуточного варианта, т.е. формирующий ее запрос может быть добавлен в главный запрос

\nCREATE TABLE #Kart(ID int identity(1,1), F1 bit, F2 bit, F3 bit, F4 bit, F5 bit, F6 bit, F7 bit, F8 bit, St tinyint)


INSERT INTO #Kart SELECT 0,1,1,0,1,0,0,1,9
INSERT INTO #Kart SELECT 0,1,0,0,0,1,0,0,2
INSERT INTO #Kart SELECT 1,0,1,0,0,0,0,1,4
INSERT INTO #Kart SELECT 0,0,0,0,0,0,1,0,1
INSERT INTO #Kart SELECT 1,1,0,0,0,0,0,1,9
INSERT INTO #Kart SELECT 0,0,0,0,1,0,0,0,2
INSERT INTO #Kart SELECT 0,0,0,0,0,0,0,1,3
INSERT INTO #Kart SELECT 0,0,1,1,1,0,0,0,9
INSERT INTO #Kart SELECT 0,0,0,1,1,0,0,0,4

create table #temp1(St tinyint)
insert #temp1 values(1)
insert #temp1 values(2)
insert #temp1 values(3)
insert #temp1 values(4)
insert #temp1 values(5)
insert #temp1 values(6)
insert #temp1 values(7)
insert #temp1 values(8 )
insert #temp1 values(9)
insert #temp1 values(10)

select a.st,
sum(cast(f1 as int)) as f1,
sum(cast(f2 as int)) as f2,
sum(cast(f3 as int)) as f3,
sum(cast(f4 as int)) as f4,
sum(cast(f5 as int)) as f5,
sum(cast(f6 as int)) as f6,
sum(cast(f7 as int)) as f7,
sum(cast(f8 as int)) as f8
into #temp2
from
(select distinct st from #kart
union
select distinct st from #temp1
) AS a
left outer join #kart b on b.st = a.st
group by a.st

select x, sum(s1) as s1, sum(s2) as s2, sum(s3) as s3, sum(s4) as s4, sum(s5) as s5, sum(s6) as s6, sum(s7) as s7, sum(s8 ) as s8, sum(s9) as s9, sum(s10) as s10
from
(select 'f'+cast(b.st as char(1)) as x,
case a.st when 1 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s1,

case a.st when 2 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s2,

case a.st when 3 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s3,

case a.st when 4 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s4,

case a.st when 5 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s5,

case a.st when 6 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s6,

case a.st when 7 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s7,

case a.st when 8 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s8,

case a.st when 9 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s9,

case a.st when 10 then
case b.st when 1 then f1
when 2 then f2
when 3 then f3
when 4 then f4
when 5 then f5
when 6 then f6
when 7 then f7
when 8 then f8
else 0
end
else 0 end as s10
from #temp2 a
cross join #temp1 b
where b.st <=8 ) AS c
group by x

drop table #kart
drop table #temp1
drop table #temp2
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022172
Владимир Смирнов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо Glory.
Если я правильно понял, вы советуете такой вариант: сначала сгруппировать по St и просуммировать поля F, а затем сделать разворот получившейся таблицы. Интересно ... надо обдумать.
Я изначально планировал группировать по F, при этом суммировать 1 по St как S1,S2...
То есть получить результат в один приём, без дополнительных (временных) таблиц.
А в отношении изменения структуры, ну Вы должны меня понять - всё уже работает, на таблицы завязаны формы, отчёты, процедуры. И из-за одного специфического отчёта (ну надо ТАК заказчику) переделывать всё нецелесообразно.
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022173
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Sergey
Если я сделаю некий view для выборки данных типа SELECT ObjectID,PropertyID,Value ...
а затем в запросе буду использовать сто подзапросов типа (SELECT Value FROM View1 WHERE PropertyID=N AND ObjectID=A.ObjectID) не будет ли его время в сто раз больше времени на выполнения запроса во view и вообще насколько полно кэшируются данные после таких запросов?

Точный ответ на такой вопрос вам даст анализ плана выполнения запроса, но IMHO SQL не должен для каждого подзапроса заново формировать результат view-а
Вы можете сами поэксперементировать со view-ом и скажем временной таблице, которая будет содержать такие же данные, но формироваться перед выполнением основного запроса.

А вообще тема оптимизации запросов очень широка и индивидуальна для каждой конкретной системы.
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022219
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Владимир Смирнов
Вопрос был чисто риторический


Да, идею вы поняли правильно. А насчет желаний заказчика, IMHO в данном случае это скорее прихоть, чем обоснованное желание, т.к. промежуточный результат(#temp2) по наглядности представления данных мало чем отличается от конечного результата.
...
Рейтинг: 0 / 0
Проблема с подзапросом
    #32022538
Alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может попробоать так?

SELECT DISTINCT
1 F,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 1) S1,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 2) S2,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 3) S3,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 4) S4,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 5) S5,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 6) S6,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 7) S7,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = S8,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 9) S9,
(SELECT SUM( CAST(F1 AS INT)) FROM KART WHERE s = 10) S10
FROM KART
UNION
SELECT DISTINCT
2,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 1) S1,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 2) S2,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 3) S3,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 4) S4,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 5) S5,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 6) S6,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 7) S7,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = S8,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 9) S9,
(SELECT SUM( CAST(F2 AS INT)) FROM KART WHERE s = 10) S10
FROM KART
UNION
SELECT DISTINCT
3,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 1) S1,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 2) S2,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 3) S3,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 4) S4,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 5) S5,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 6) S6,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 7) S7,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = S8,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 9) S9,
(SELECT SUM( CAST(F3 AS INT)) FROM KART WHERE s = 10) S10
FROM KART
UNION
SELECT DISTINCT
4,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 1) S1,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 2) S2,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 3) S3,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 4) S4,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 5) S5,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 6) S6,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 7) S7,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = S8,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 9) S9,
(SELECT SUM( CAST(F4 AS INT)) FROM KART WHERE s = 10) S10
FROM KART
UNION
SELECT DISTINCT
5,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 1) S1,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 2) S2,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 3) S3,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 4) S4,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 5) S5,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 6) S6,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 7) S7,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = S8,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 9) S9,
(SELECT SUM( CAST(F5 AS INT)) FROM KART WHERE s = 10) S10
FROM KART
UNION
SELECT DISTINCT
6,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 1) S1,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 2) S2,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 3) S3,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 4) S4,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 5) S5,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 6) S6,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 7) S7,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = S8,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 9) S9,
(SELECT SUM( CAST(F6 AS INT)) FROM KART WHERE s = 10) S10
FROM KART
UNION
SELECT DISTINCT
7,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 1) S1,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 2) S2,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 3) S3,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 4) S4,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 5) S5,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 6) S6,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 7) S7,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = S8,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 9) S9,
(SELECT SUM( CAST(F7 AS INT)) FROM KART WHERE s = 10) S10
FROM KART
UNION
SELECT DISTINCT
8,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 1) S1,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 2) S2,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 3) S3,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 4) S4,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 5) S5,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 6) S6,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 7) S7,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = S8,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 9) S9,
(SELECT SUM( CAST(F8 AS INT)) FROM KART WHERE s = 10) S10
FROM KART
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Проблема с подзапросом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]