powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
15 сообщений из 15, страница 1 из 1
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39689866
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите пожалуйста как выбрать все поля таблицы @Sensors, и значения из @SensorValue, если там таковые имеются.
Получается получить только поля, у которых есть значение. А нужны все поля.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
--список всех датчиков
declare @Sensors table([Name] varchar(10), id int)
insert into @Sensors(name, id)
select 'Датчик 1', 1 union all
select 'Датчик 2', 2 union all
select 'Датчик 3', 3  

--таблица значений дачиков
declare @SensorValue table(ID int, SensorID int, SensorValue nvarchar(10))
insert into @SensorValue(ID, SensorID, SensorValue)
select 1, 1, 'Запущен' union all
select 2, 3, 'Остановлен' 



в результат нужно вывести названия всех датчиков, независимо, есть у него значение или нет. если нет, то выводить NULL или пустую строку. Нужно, чтобы получился вот такой результат:
Код: plaintext
1.
2.
3.
Name,	SensorValue
Датчик 1	'Запущен'
Датчик 2	NULL
Датчик 3	'Остановлен'
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39689891
SELECT, LEFT OUTER JOIN, ORDER BY.
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39689902
Владимир Затуливетер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
select s.Name
     , s.id
     , v.SensorValue
from @Sensors s
	left join @SensorValue v on s.id = v.SensorID
order by s.Name
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690021
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир Затуливетер, большое вам спасибо!

Работало, пока не пришлось усложнить условия. Просьба ещё раз взглянуть и посоветовать решение.
В первой таблице перечислены датчики определённых механизмов. У каждого механизма есть свой набор датчиков:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
--список всех датчиков механизмов
declare @Sensors table([Name] varchar(10), id int, mechanism int)
insert into @Sensors(name, id, mechanism)
select 'Датчик 1', 1, 1 union all
select 'Датчик 2', 2, 1 union all
select 'Датчик 3', 3, 1 union all
select 'Датчик 7', 4, 2 union all
select 'Датчик 9', 5, 2  

--таблица наборов со значениями дачиков
declare @SensorValue table(SensorID int, SensorValue nvarchar(10), SetID int)
insert into @SensorValue(SensorID, SensorValue, SetID)
select 1, 'Запущен', 1 union all
select 3, 'Остановлен', 1 union all
select 3, 'Остановлен', 2 union all
select 4, 'Запущен', 2



а во второй таблице содержатся значения и номера наборов этих значений.
теперь я хочу получить значения набора данных №2 (SetID=2) всех датчиков механизма №1 (Mechanism=1), делаю такое условие:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select s.Name
     , s.id
     , v.SensorValue
	 , v.SetID
from @Sensors s
	left join @SensorValue v on s.id = v.SensorID
where v.SetID = 2 and s.mechanism = 1	
order by s.[Name]


а в ответ:
Код: plaintext
1.
Name		id	SensorValue	SetID
Датчик 3	3	Остановлен		2

а как добиться, чтобы выводились все датчики этого механизма, даже если по каким-либо из них нет значения
Код: plaintext
1.
2.
3.
Name		id	SensorValue	SetID
Датчик 1	1	NULL		NULL
Датчик 2	2	NULL		NULL
Датчик 3	3	Остановлен		2
??

или же, если условие такое:
where v.SetID = 2 and s.mechanism = 2
то такой результат:
Код: plaintext
1.
2.
3.
Name		id	SensorValue	SetID
Датчик 7	4	Запушен		2
Датчик 9	1	NULL		NULL
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690022
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
palladin600,

перенесите условия, накладываемые на поля правой таблицы LEFT JOINа из WHERE в ON.
В данном случае
Код: sql
1.
and s.mechanism = 1
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690028
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iap, что ничего не клеится, уже всякие джойны перепробовал, выдаёт не то что надо
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select s.Name
     , s.id
     , v.SensorValue
	 , v.SetID
from @Sensors s
	right join @SensorValue v on s.id = v.SensorID and s.mechanism = 2 
	where v.SetID = 2
order by s.[Name]


выдаёт:
Код: plaintext
1.
2.
Name		id	SensorValue	SetID
NULL		NULL	Остановлен	2
Датчик 7	4	Запущен		2

а нужно:
Код: plaintext
1.
2.
3.
Name		id	SensorValue	SetID
Датчик 7	4	Запушен		2
Датчик 9	5	NULL		NULL
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690042
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
palladin600,

Думать нужно, а не гадать
Код: sql
1.
2.
3.
4.
5.
6.
7.
select
 s.Name, s.id, sv.SensorValue, sv.SetID
from
 @Sensors s left join
 @SensorValue sv on sv.SensorID = s.id
where
 s.mechanism = 2;
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690057
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmpalladin600,

Думать нужно, а не гадать

Ну это я с удовольствием. А когда не выходит, то что поделать...
Вот и в вашем совете-примере, если поставить условие s.mechanism = 1, то выдаст почему-то задвоенные данные.
Код: plaintext
1.
2.
3.
4.
Name		id	SensorValue	SetID
Датчик 1	1	Запущен		1
Датчик 2	2	NULL		NULL
Датчик 3	3	Остановлен	1
Датчик 3	3	Остановлен	2
тут выдал ещё последнюю запись где SetID = 2, а надо только где SetID = 1,

как отфильтровать?
сделал так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
select
 s.Name, s.id, sv.SensorValue, sv.SetID
from
 @Sensors s left join
 @SensorValue sv on sv.SensorID = s.id
where
 s.mechanism = 1 and (sv.SetID = 1 or sv.SetID is null);



работает, но тогда, если поставить фильтр SetID = 2, то выдаёт результаты странные:
Код: plaintext
1.
2.
Name		id	SensorValue	SetID
Датчик 2	2	NULL		NULL
Датчик 3	3	Остановлен	2


а нужно:
Код: plaintext
1.
2.
3.
Name		id	SensorValue	SetID
Датчик 1	1	NULL		NULL
Датчик 2	2	NULL		NULL
Датчик 3	3	Остановлен	2

Спасибо большое!
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690069
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
palladin600если поставить условие s.mechanism = 1, то выдаст почему-то задвоенные данные.Потому что в @SensorValue две строки для "Датчик 3".
Сервер не умеет читать ваши мысли. А вы, пока что, не можете внятно сформулировать задачу.
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690127
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сорри, что запарил уже,
Извините, вот по полочкам разложу.
Есть устройства (mechanism), у которых есть свои наборы датчиков (sensors).

И есть таблица, в которой содержатся настройки этих датчиков.

Нужно получить набор значений датчиков для определённого устройства.

Т.е., предположим, что есть Устройство1, у которого прописано 3 датчика: Датчик1-3. К этому устройству есть также готовый набор значений (SetID) для датчиков.

Я хочу выбрать определённое устройство, и посмотреть значения по выбранному набору настроек.

Если разбирать последовательно задачу, то я должен вначале получить список всех датчиков интересующего меня устройства из таблицы @Sensors, где:
Код: plaintext
1.
2.
3.
Mechanism = 1
	Датчик1
	Датчик2
	Датчик3
иными словами, я могу выбрать только одно устройство для отчёта.

затем, я получаю значения конкретного набора значений для датчиков этого устройства из таблицы @SensorValue, где:
Код: plaintext
1.
2.
SetID = 1
	Датчик1 = 'Запушен'
	Датчик2 = 'Остановлен'

и сопоставляю эти значения с датчиками устройства:
Код: vbnet
1.
2.
3.
4.
5.
6.
For Each Sensor In Mechanism.Sensors
	If Sensor.Name = SensorValue.Name
		'если id датчика совпадает, то уставливаем значение
		Mechanism.Sensor.Value = SensorValue("Датчик1").SensorValue
	End if
Next


(цикл приведён примитивный, для наглядности)

в итоге, я получаю картину, что для Устройства1:
Код: plaintext
1.
2.
для Датчик1 есть значение равное 'Запущен'
для Датчик2 не нашлось значения, т.е. NULL
для Датчик3 есть значение равное 'Остановлен'


если выставить условие SetID = 2, то получим уже другой набор значений датчиков для устройства (Mechnanism = 1)
Код: plaintext
1.
2.
для Датчик1 не нашлось значения, т.е. NULL
для Датчик2 не нашлось значения, т.е. NULL
для Датчик3 есть значение равное 'Остановлен'

и, если бы я ввёл несуществующй набор, скажем SetID = 3, то в ответ бы получил просто список датчиков с отсутсвующими значениями:
Код: plaintext
1.
2.
3.
для Датчик1 не нашлось значения, т.е. NULL
для Датчик2 не нашлось значения, т.е. NULL
для Датчик3 не нашлось значения, т.е. NULL

Может двумя запросами это можно сделать, но список датчиков должен быть всегда, независимо, есть набор значений или же нету. Или же, может перенести/добавить нужно поле какое-то в таблицу, чтобы по-правильному, как говорится.
Ну вот в общем, такие дела. Конечно, можно двумя запросами делать, и потом городить на клиенте цикл с сопоставлениями, но так хочется по-грамотному через t-sql реализовать.
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690145
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вникни в понятие Derived Table.

Код: sql
1.
2.
3.
4.
5.
6.
with s as ( select * from @Sensors where mechanism = 1 )
    , sv as ( select * from @SensorValue  where SetID = 1 )
select
 s.Name, s.id, sv.SensorValue, sv.SetID
from  s left join sv on sv.SensorID = s.id
;
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690160
Посетитель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну или то же самое без cte

Код: sql
1.
2.
3.
4.
5.
6.
select s.Name, s.id, sv.SensorValue, sv.SetID
  from @Sensors s 
  left join @SensorValue sv 
    on sv.SensorID = s.id
   and sv.SetID = 1
 where s.mechanism = 1;
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690164
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посетительну или то же самое без cte

Код: sql
1.
2.
3.
4.
5.
6.
select s.Name, s.id, sv.SensorValue, sv.SetID
  from @Sensors s 
  left join @SensorValue sv 
    on sv.SensorID = s.id
   and sv.SetID = 1
 where s.mechanism = 1;



Не учи плохому. Без СТЕ надо так

Код: sql
1.
2.
3.
4.
5.
select
 s.Name, s.id, sv.SensorValue, sv.SetID
from  ( select * from @Sensors where mechanism = 1 )
 as s left join ( select * from @SensorValue  where SetID = 1 ) as sv on sv.SensorID = s.id
;
...
Рейтинг: 0 / 0
Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
    #39690167
Посетитель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222Посетительну или то же самое без cte

Код: sql
1.
2.
3.
4.
5.
6.
select s.Name, s.id, sv.SensorValue, sv.SetID
  from @Sensors s 
  left join @SensorValue sv 
    on sv.SensorID = s.id
   and sv.SetID = 1
 where s.mechanism = 1;



Не учи плохому. Без СТЕ надо так

Код: sql
1.
2.
3.
4.
5.
select
 s.Name, s.id, sv.SensorValue, sv.SetID
from  ( select * from @Sensors where mechanism = 1 )
 as s left join ( select * from @SensorValue  where SetID = 1 ) as sv on sv.SensorID = s.id
;



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

Заскрипело приложеньице-то!

Все три варианта решений от 'aleks222' и 'Посетитель' выдали то, что нужно.
И с СТЕ и без.

Спасибо за квалифицированную помощь.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Выборка всех полей основной таблицы, даже если нет значений у вспомогательной
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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