powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / добавить условие в сложный join
25 сообщений из 33, страница 1 из 2
добавить условие в сложный join
    #39998157
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Не совсем понимаю как дополнить мой запрос логическим условием.

Есть 2 таблицы: описание счетчиков, показания счетчиков.

id descr foreign_id20 счетчик 1 21 счетчик 2 2424 счетчик 3
id DateTime pow20 2017-02-14 18:59:07.000 23305.221 2017-02-14 18:59:07.000 31051.924 2017-02-14 18:59:07.000 60832.3
и мой запрос, который считает значение на начало дня, на конец дня и разницу между началом и концом

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select  a.id
		,convert(varchar(20),a.datetime,120) as first_date
		,round(a.pow,1) as first_value
		,convert(varchar(20),b.datetime,120) as last_date
		,round(b.pow,1) as last_value
		,round(b.pow - a.pow,1) as sum
from(
select top 1 with ties *
from [meter]
where day(datetime) in (14) and month(datetime) in (2) and year(datetime) in (2017)
order by row_number() over (partition by id, year(datetime),month(datetime),day(datetime) order by datepart(hour,datetime) asc,datepart(minute,datetime) asc, datepart(second,datetime) asc)
) a
join(
select top 1 with ties *
from [meter]
where day(datetime) in (14) and month(datetime) in (2) and year(datetime) in (2017)
order by row_number() over (partition by id, year(datetime),month(datetime),day(datetime) order by datepart(hour,datetime) desc,datepart(minute,datetime) desc, datepart(second,datetime) desc)
) b
on a.id = b.id and convert(varchar(8),a.datetime,112) = convert(varchar(8),b.datetime,112)



Результат запроса:
id first_date first_value last_date last_value sum20 2017-02-14 18:59:07 23305.2 2017-02-14 23:00:01 23367.1 61.921 2017-02-14 18:59:07 31051.9 2017-02-14 23:00:01 31110.4 58.524 2017-02-14 18:59:07 60832.3 2017-02-14 23:00:01 60911.4 79.1
Мне нужно добавить условие, что если из таблицы описания счетчиков для определенного id есть значение foreign_id, то мне необходимо делать разницу не между показаниями счетчиков с id, а разницу между показаниями foreign_id

Прошу помочь.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #39998178
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot
Код: sql
1.
where day(datetime) in (14) and month(datetime) in (2) and year(datetime) in (2017)




Одно только ЭТО отшибает фсякое желание.
Чо над сервером то издеваться?
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #39998180
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m where '20170214'<= [datetime] and [datetime] < '20170215' group by id, foreign_id )
select  d0.id, real_id = d.id
		,convert(varchar(20),a.datetime,120) as first_date
		,round(a.pow,1) as first_value
		,convert(varchar(20),b.datetime,120) as last_date
		,round(b.pow,1) as last_value
		,round(b.pow - a.pow,1) as sum
    from d as d0 
         inner join d on d.id = d0.foreign_id
         left outer join m as a on a.id = d.id and a.datetime = d.fdate
         left outer join m as b on b.id = d.id and b.datetime = d.ldate
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #39998195
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
artgot
Код: sql
1.
where day(datetime) in (14) and month(datetime) in (2) and year(datetime) in (2017)




Одно только ЭТО отшибает фсякое желание.
Чо над сервером то издеваться?


Подскажите что не так в этом выражении? это кусок запроса из отчёта, где пользователь может делать выборку по датам.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #39998200
Oleg_SQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
artgot,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
DECLARE @i INT = 123;
SELECT 'Можно сравнить вот так' AS col
 WHERE SUBSTRING(CAST(@i AS VARCHAR), 1, 1) = 1
       AND SUBSTRING(CAST(@i AS VARCHAR), 2, 1) = 2
       AND SUBSTRING(CAST(@i AS VARCHAR), 3, 1) = 3
UNION
SELECT 'А можно и так )))' AS col
 WHERE @i = 123;




И еще, так ли важно называть поля "datetime" ?
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #39998374
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot
aleks222
пропущено...


Одно только ЭТО отшибает фсякое желание.
Чо над сервером то издеваться?


Подскажите что не так в этом выражении? это кусок запроса из отчёта, где пользователь может делать выборку по датам.


Индексы отдыхают, а сервер работает.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #39998444
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
artgot
пропущено...


Подскажите что не так в этом выражении? это кусок запроса из отчёта, где пользователь может делать выборку по датам.


Индексы отдыхают, а сервер работает.


Как тогда правильно?
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #39998479
asdor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot

Как тогда правильно?

Вам же aleks222 написал как надо. А Oleg_SQL еще и разжевал.
Ваше
Код: sql
1.
day(datetime) in (14) and month(datetime) in (2) and year(datetime) in (2017) = '20170214'
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40004918
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m where '20170214'<= [datetime] and [datetime] < '20170215' group by id, foreign_id )
select  d0.id, real_id = d.id
		,convert(varchar(20),a.datetime,120) as first_date
		,round(a.pow,1) as first_value
		,convert(varchar(20),b.datetime,120) as last_date
		,round(b.pow,1) as last_value
		,round(b.pow - a.pow,1) as sum
    from d as d0 
         inner join d on d.id = d0.foreign_id
         left outer join m as a on a.id = d.id and a.datetime = d.fdate
         left outer join m as b on b.id = d.id and b.datetime = d.ldate



Здравствуйте.

Ещё 2 вопроса:

1. как добавить в результирующую таблицу значение pow не от foreign_id, а от id, т.е. чтобы разница была как написано, а first_value и last_value от оригинального id.
2. возможно ли, выводить pow и разницу оригинального id, если в этот день не было показаний foreign_id.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40005099
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m where '20170214'<= [datetime] and [datetime] < '20170215' group by id, foreign_id )
select  d0.id, real_id = d.id
		,convert(varchar(20),a.datetime,120) as first_date

		,round(a.pow,1) as first_value
		,round(a0.pow,1) as first_value0

		,convert(varchar(20),b.datetime,120) as last_date

		,round(b.pow,1) as last_value
		,round(b0.pow,1) as last_value0

		,round(b.pow - a.pow,1) as sum
    from d as d0 
         inner join d on d.id = d0.foreign_id
         left outer join m as a on a.id = d.id and a.datetime = d.fdate
         left outer join m as b on b.id = d.id and b.datetime = d.ldate

         left outer join m as a0 on a0.id = d0.id and a0.datetime = d0.fdate
         left outer join m as b0 on b0.id = d0.id and b0.datetime = d0.ldate
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40005992
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m where '20170214'<= [datetime] and [datetime] < '20170215' group by id, foreign_id )
select  d0.id, real_id = d.id
		,convert(varchar(20),a.datetime,120) as first_date

		,round(a.pow,1) as first_value
		,round(a0.pow,1) as first_value0

		,convert(varchar(20),b.datetime,120) as last_date

		,round(b.pow,1) as last_value
		,round(b0.pow,1) as last_value0

		,round(b.pow - a.pow,1) as sum
    from d as d0 
         inner join d on d.id = d0.foreign_id
         left outer join m as a on a.id = d.id and a.datetime = d.fdate
         left outer join m as b on b.id = d.id and b.datetime = d.ldate

         left outer join m as a0 on a0.id = d0.id and a0.datetime = d0.fdate
         left outer join m as b0 on b0.id = d0.id and b0.datetime = d0.ldate



Спасибо, но не выводит строки, если в этом дне нет записи с foreign_id, может ли запрос возвращать с реальными значениями, если в этот день нет записи с foreign_id?

Ещё вопрос, посмотрел по времени выполнения, разница по сравнению с оригинальным запросом по времени выполнения почти в 2 раза, может имеет смысл сделать хранимую процедуру для заполнения значений, чем нагружать отчеты?
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40006044
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извини, дарагой, мне уже наскучило тривиальные вещи писать.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40006425
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222,

С этим разобрался, всё понял. Могу с Вами лично пообщаться?
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40006435
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot
aleks222,

С этим разобрался, всё понял. Могу с Вами лично пообщаться?


Мне нечего скрывать от народа.
Пиши здесь.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40006483
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222,

мне надо "допилить" отчеты (всего 3шт), есть замечания, типа вот этих, которые надо закрыть. Можем договориться с вами на консультации по TeamViewer, например, или закончить мои отчеты (думаю это не лучший вариант, чтобы во все нюансы не погружаться) на финансовой основе?
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40006503
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot
aleks222,

мне надо "допилить" отчеты (всего 3шт), есть замечания, типа вот этих, которые надо закрыть. Можем договориться с вами на консультации по TeamViewer, например, или закончить мои отчеты (думаю это не лучший вариант, чтобы во все нюансы не погружаться) на финансовой основе?

Не, я на коммерческой основе не консультирую. Этой фигни мне на работе хватает.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40006533
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222,

Понял , буду благодарен если поможете "точечно".

Как вот это условие:

where '20170214'<= [datetime] and [datetime] < '20170215'

преобразовать если мне надо несколько дней учитывать (например 14, 26, 28). У меня было вот так:

where day(datetime) in (14, 26, 28)

Но сейчас это условие не работает.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40006542
Агрох
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot, заведи через with таблицу с датами и джойн на неё.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40006569
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot
aleks222,

Понял , буду благодарен если поможете "точечно".

Как вот это условие:

where '20170214'<= [datetime] and [datetime] < '20170215'

преобразовать если мне надо несколько дней учитывать (например 14, 26, 28). У меня было вот так:

where day(datetime) in (14, 26, 28)

Но сейчас это условие не работает.


Код: sql
1.
2.
3.
4.
declare @dts table(dt date primary key);
insert @dts values('20170214'),('20170226'),('20170228');
...
where exists( select * from @dts as x where x.dt = t.[datetime])



Код: sql
1.
where exists( select * from  (values('20170214'),('20170226'),('20170228') ) as x(dt) where x.dt = t.[datetime])
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40013964
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
artgot
aleks222,

Понял , буду благодарен если поможете "точечно".

Как вот это условие:

where '20170214'<= [datetime] and [datetime] < '20170215'

преобразовать если мне надо несколько дней учитывать (например 14, 26, 28). У меня было вот так:

where day(datetime) in (14, 26, 28)

Но сейчас это условие не работает.


Код: sql
1.
2.
3.
4.
declare @dts table(dt date primary key);
insert @dts values('20170214'),('20170226'),('20170228');
...
where exists( select * from @dts as x where x.dt = t.[datetime])



Код: sql
1.
where exists( select * from  (values('20170214'),('20170226'),('20170228') ) as x(dt) where x.dt = t.[datetime])



Извините, я не понимаю, как эту конструкцию вставить сюда:

Код: sql
1.
2.
3.
with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m where '20170214'<= [datetime] and [datetime] < '20170215' group by id, foreign_id )
select  d0.id, real_id = d.id
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40013988
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot
aleks222
пропущено...


Код: sql
1.
2.
3.
4.
declare @dts table(dt date primary key);
insert @dts values('20170214'),('20170226'),('20170228');
...
where exists( select * from @dts as x where x.dt = t.[datetime])



Код: sql
1.
where exists( select * from  (values('20170214'),('20170226'),('20170228') ) as x(dt) where x.dt = t.[datetime])



Извините, я не понимаю, как эту конструкцию вставить сюда:

Код: sql
1.
2.
3.
with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m where '20170214'<= [datetime] and [datetime] < '20170215' group by id, foreign_id )
select  d0.id, real_id = d.id



Код: sql
1.
2.
3.
4.
5.
6.
7.
declare @dts table(dt date primary key);
insert @dts values('20170214'),('20170226'),('20170228');

with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m 
where exists( select * from @dts as x where x.dt = t.[datetime]) group by id, foreign_id 
)
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40014075
artgot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
artgot
пропущено...


Извините, я не понимаю, как эту конструкцию вставить сюда:

Код: sql
1.
2.
3.
with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m where '20170214'<= [datetime] and [datetime] < '20170215' group by id, foreign_id )
select  d0.id, real_id = d.id



Код: sql
1.
2.
3.
4.
5.
6.
7.
declare @dts table(dt date primary key);
insert @dts values('20170214'),('20170226'),('20170228');

with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m 
where exists( select * from @dts as x where x.dt = t.[datetime]) group by id, foreign_id 
)



Я так понимаю, здесь должно быть

select * from @dts as x where x.dt = m.datetime

Но так возвращает пустой запрос.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40014523
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
artgot

Но так возвращает пустой запрос.


1. У тя даты "с секундами" в таблице?

Код: sql
1.
2.
3.
4.
5.
6.
7.
declare @dts table(dt date primary key);
insert @dts values('20170214'),('20170226'),('20170228');

with m as ( select * from [meter] )
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m 
where exists( select * from @dts as x where m.[datetime] between x.dt and dateadd(day, 1, x.dt ) ) group by id, foreign_id 
)0



2. Даты то есть ли?
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40014529
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это ж фсе тупо и незатейливо проверяется


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
declare @dts table(dt date primary key);
insert @dts values('20170214'),('20170226'),('20170228');

with m as ( select * from [meter] as m where exists( select * from @dts as x where m.[datetime] between x.dt and dateadd(day, 1, x.dt ) ) )
  select * from m;
-- должон быть результат

with m as ( select * from [meter] as m where exists( select * from @dts as x where m.[datetime] between x.dt and dateadd(day, 1, x.dt ) ))
   , d as ( select id, foreign_id = isnull(foreign_id, id), fdate = min([datetime]), ldate = max([datetime]) from m group by id, foreign_id  )
  select * from d;
-- тогда и тут будет результат

-- запросы, по первости, следует писать "понемногу" мелкими прыжками в сторону результата.
...
Рейтинг: 0 / 0
добавить условие в сложный join
    #40014574
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
Чо над сервером то издеваться?

Это, скорее всего, просто, сгенерированный запрос, где вместо скалярных значений может быть и список (например, в зависимости от выбора значений пользователем).

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


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