Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
Добрый день!
Есть таблица со списком стоблцов
CREATE TABLE [dbo].[IP_Map](
	[id_station] [uniqueidentifier] NULL,
	[Station_name] [varchar](16) NOT NULL,
	[IP] [varchar](16) NOT NULL,
	[active] [tinyint] NULL
) ON [PRIMARY]


В поле station_name данные хранятся в виде названий столбцов (T1R, T1L и т.д.) в другой таблице.

Вот она:
CREATE TABLE [dbo].[Stations](
	[body_number] [int] IDENTITY(1,1) NOT NULL,
	[body_id] [uniqueidentifier] NOT NULL,
	[T1R] [int] NOT NULL,
	[T1L] [int] NULL,
	[T4R] [int] NULL,
	[T5R] [int] NULL,
	[T5L] [int] NULL,
	[T6R] [int] NULL,
	[T6L] [int] NULL,
	[T7R] [int] NULL,
	[T7L] [int] NULL,
	[T8R] [int] NULL,
	[T8L] [int] NULL,
 CONSTRAINT [PK_Stations] PRIMARY KEY CLUSTERED 
(
	[body_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]


Выполняю такой запрос:
    SELECT top 40 
		main.body_id, 
		main.body_number,
		stations.body_number,
		main.sequence_number,
		main.suffix,
                stations.T1R,
                stations.T6L
	  FROM Stations
		inner join main on
		main.body_id=stations.body_id
	  where stations.body_number<=
		(select max(body_number) from Stations)
	  order by stations.body_number desc


он работает, но он неудобен.

мне хотелось бы переписать его так, чтобы выборка полей stations.T% происходила на основании флага active в таблице IP_Map.

Т.е. например, в случае если стоит флаг active у записей ip_map.station_name = 'T1R' и ip_map.station_name = 'T8R', то запрос динамически бы преобразовался в что-то наподобие такого

    SELECT top 40 
		main.body_id, 
		main.body_number,
		stations.body_number,
		main.sequence_number,
		main.suffix,
                stations.T1R,
                stations.T8R
	  FROM Stations
		inner join main on
		main.body_id=stations.body_id
	  where stations.body_number<=
		(select max(body_number) from Stations)
	  order by stations.body_number desc


Я очень надеюсь, что понятно объяснил. :)

Если я правильно представляю процесс, то сначала я должен произвести выборку из IP_Map where active=1
Далее, я должен как-то подставить результаты в запрос из таблицы Stations, а как это сделать я пока не могу понять.

Коллеги, возможно ли такое решение?
Если да, то как это реализовать?

Никогда не бойся делать то, что не умеешь.
Помни, профессионалы построили Титаник, а Ковчег любители.
5 мар 14, 08:32    [15674059]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
invm
Member

Откуда: Москва
Сообщений: 9824
1. Как вы себе представляете этот запрос, когда для разных body_number разные наборы столбцов?
2. Условие stations.body_number<= (select max(body_number) from Stations) эквивалентно выборке из всей таблицы Stations.
5 мар 14, 09:32    [15674234]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
invm,

К сожалению,
тут вкралась досадная ошибка :(
main.body_number и stations.body_number это не одно и тоже.
stations.body_number это inc поле, просто счетчик строк таблицы.
main.body_number - конкретное число от 1 до 999
5 мар 14, 09:51    [15674355]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Glory
Member

Откуда:
Сообщений: 104751
Kast2K
Т.е. например, в случае если стоит флаг active у записей ip_map.station_name = 'T1R' и ip_map.station_name = 'T8R', то запрос динамически бы преобразовался в что-то наподобие такого

Т.е. для каждой записи должен быть свой список полей что ли ?
И как это визуально должно выглядеть ?
5 мар 14, 10:16    [15674502]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
Glory,

приблизительно такой выхлоп хочется увидеть
    SELECT top 40 
		main.body_id, 
		main.body_number as body_number_main,
		stations.body_number,
		main.sequence_number,
		main.suffix,
                stations.T1R,
                stations.T8R
	  FROM Stations
		inner join main on
		main.body_id=stations.body_id
	  where stations.body_number<=
		(select max(body_number) from Stations)
	  order by stations.body_number desc



body_id body_number_main body_number sequence_number suffix T1R T8R
E6F6B1A1-C30E-4C30-8734-F0FF36031D1E 00680 73722 632 B4 1 1
0A0F3C76-4AF6-4339-AAD7-E5654E4111B2 00681 73721 631 B8 1 1
5 мар 14, 10:21    [15674536]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Glory
Member

Откуда:
Сообщений: 104751
Kast2K
приблизительно такой выхлоп хочется увидеть

Вы не поняли
Например, есить две записи с _разными_ " флаг active "
Одна записи, должна быть с T1R/T8R, а вторая с T2R/T11R
Как будет выглядеть результат выборки этих двух записей ?
5 мар 14, 10:26    [15674594]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
Glory,

Простите, действительно, я видимо не совсем вас понимаю.

Мне необходимо следующее:
таблица IP_map
если так
station_name active
T1R 1
T2L 0
T3L 0
T8R 1
то
    SELECT top 40 
		main.body_id, 
		main.body_number as body_number_main,
		stations.body_number,
		main.sequence_number,
		main.suffix,
                stations.T1R,
                stations.T8R
	  FROM Stations
		inner join main on
		main.body_id=stations.body_id
	  where stations.body_number<=
		(select max(body_number) from Stations)
	  order by stations.body_number desc


А если так
таблица IP_map

station_name active
T1R 0
T2L 1
T3L 1
T8R 1

то

    SELECT top 40 
		main.body_id, 
		main.body_number as body_number_main,
		stations.body_number,
		main.sequence_number,
		main.suffix,
                stations.T2L,
                stations.T3L,
                stations.T8R
	  FROM Stations
		inner join main on
		main.body_id=stations.body_id
	  where stations.body_number<=
		(select max(body_number) from Stations)
	  order by stations.body_number desc



простите, за корявость изложения :(
5 мар 14, 10:33    [15674652]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Glory
Member

Откуда:
Сообщений: 104751
Kast2K
таблица IP_map
если так
station_name active
T1R 1
T2L 0
T3L 0
T8R 1
то

У вас что в IP_map строго одна запись ?
5 мар 14, 10:35    [15674671]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
Glory,

Да.

Все записи уникальны.
5 мар 14, 10:37    [15674691]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
вот пример

К сообщению приложен файл. Размер - 11Kb
5 мар 14, 10:41    [15674714]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Glory
Member

Откуда:
Сообщений: 104751
Kast2K
Glory,

Да.

Все записи уникальны.

Вешаете на таблицу триггер.
Который при изменении данных будет (пере)создавать представление с нужным текстом запроса.
5 мар 14, 10:41    [15674717]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
Glory,

Простите, но ведь триггер не применяется на Select
http://msdn.microsoft.com/ru-ru/library/ms189799.aspx

или я не прав?
5 мар 14, 10:51    [15674797]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Glory
Member

Откуда:
Сообщений: 104751
Kast2K
Glory,

Простите, но ведь триггер не применяется на Select
http://msdn.microsoft.com/ru-ru/library/ms189799.aspx

или я не прав?

Триггер на таблицу [IP_Map] сделает представление. К которому вы и будет обращаться в своем Select
5 мар 14, 10:54    [15674826]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
Glory,

не могли бы вы привести пример или кинуть ссылочку на доку.

Спасибо.
5 мар 14, 10:59    [15674870]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Kast2K
Member

Откуда: Санкт-Петербург
Сообщений: 520
Решил проще

ALTER PROCEDURE [dbo].[TestTrim]
AS
BEGIN
	DECLARE @MyCOLUMNS nvarchar(1024)
	declare @ttrim nvarchar (max)
	
	SET NOCOUNT ON;
	
	select @ttrim=ISNULL(@ttrim+', stations.','stations.')+ Station_name from IP_Map where ip_map.active=1
    -- Insert statements for procedure her
	
	set @MyCOLUMNS='select top 100 '+@ttrim+' from Stations order by body_number desc'

	set @MyCOLUMNS='    SELECT top 40 
		main.body_id, 
		main.body_number,
		stations.body_number,
		main.sequence_number,
		main.suffix, '+@ttrim+
		' FROM Stations
		inner join main on
		main.body_id=stations.body_id
	  where stations.body_number<=
		(select max(body_number) from Stations)
	  order by stations.body_number desc'
	
	exec (@MyCOLUMNS)
	
END


Glory,
Огромное спасибо за помощь!
5 мар 14, 11:15    [15675026]     Ответить | Цитировать Сообщить модератору
 Re: Выборка столбцов таблицы на основании выборки строк из другой таблицы  [new]
Веrd
Member

Откуда: Лазаревское
Сообщений: 588
Kast2K
Тяжело было бы спорить с отписавшимся выше человеком - т.к. я опытом для этого не вышел пока.
Но тем не менее.

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

Можно решить проблему динамическим SQL, как сделал ТС.

Но, ИМХО, оба варианта - сорта говна.

При большом объёме данных, такая организация таблицы даст много проблем:
CREATE TABLE [dbo].[Stations](
	[body_number] [int] IDENTITY(1,1) NOT NULL,
	[body_id] [uniqueidentifier] NOT NULL,
	[T1R] [int] NOT NULL,
	[T1L] [int] NULL,
	[T4R] [int] NULL,
	[T5R] [int] NULL,
	[T5L] [int] NULL,
	[T6R] [int] NULL,
	[T6L] [int] NULL,
	[T7R] [int] NULL,
	[T7L] [int] NULL,
	[T8R] [int] NULL,
	[T8L] [int] NULL,
 CONSTRAINT [PK_Stations] PRIMARY KEY CLUSTERED 
(
	[body_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]


Вместо вот этой фигни:
              [T1R] [int] NOT NULL,
	[T1L] [int] NULL,
	[T4R] [int] NULL,
	[T5R] [int] NULL,
	[T5L] [int] NULL,
	[T6R] [int] NULL,
	[T6L] [int] NULL,
	[T7R] [int] NULL,
	[T7L] [int] NULL,
	[T8R] [int] NULL,
	[T8L] [int] NULL,


Надо сделать ещё 2 таблицы.

В одной хранить от Id: T1L, T4R, ...

А в другой хранить 3 поля:
1. Непосредственно значение.
2. Ссылка на Id.
3. Ссылка на элемент таблицы Stations

Это позволит:
1. Очень просто расширять список этих полей.
2. При правильно построенных индексах даст выигрыш в производительности.

Надо просто вытребовать от 8 до 25 часов на рефакторинг этого решения.
Иначе в будущем могут возникнуть проблемы.


5 мар 14, 11:44    [15675360]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить