Отправляет email-рассылки с помощью сервиса Sendsay

RFpro.ru: Базы данных MySQL

  Все выпуски  

RusFAQ.ru: Базы данных SQL


Новое направление Портала RusFAQ.ru:
MosHoster.ru - Профессиональный хостинг

РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / Базы данных SQL

Выпуск № 347
от 26.02.2008, 22:35

Администратор:Калашников О.А.
В рассылке:Подписчиков: 449, Экспертов: 51
В номере:Вопросов: 2, Ответов: 10

Нам важно Ваше мнение об этой рассылке.
Оценить этот выпуск рассылки >>


Вопрос № 124152: Уважаемые эксперты, приведённым в приложении запросом я считаю колличество записей с уникальным ip и free равным нулю. Мне нужно модифицировать данный запрос так, чтобы он возвращал так-же(т.е. сразу 2 значения) колличество уникальных ip с f...
Вопрос № 124216: Здравствуйте. Есть оборудование, которое периодически включается и выключается. Данные о статусе оборудования заносятся в таблицу, в которой поля - id(номер оборудования), datestatus(дата изменения статуса), status(1-включили, 0-выключили). То есть i...

Вопрос № 124.152
Уважаемые эксперты, приведённым в приложении запросом я считаю колличество записей с уникальным ip и free равным нулю.

Мне нужно модифицировать данный запрос так, чтобы он возвращал так-же(т.е. сразу 2 значения) колличество уникальных ip с free равным единице.
Спасибо.

Приложение:

Отправлен: 21.02.2008, 05:29
Вопрос задал: Миленин Александр (статус: Студент)
Всего ответов: 6
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Raptor3
Здравствуйте, Миленин Александр!

select count(distinct(ip)) from lan where free=0 or (free=1) group by free

select count(distinct(ip)),free from lan where free=0 or (free=1) group by free
(кол-во и тип 0 или 1)
---------
Программист - это человек который решает проблему, о которой вы не знаете, способом который вы не понимаете
Ответ отправил: Raptor3 (статус: 5-ый класс)
Ответ отправлен: 21.02.2008, 05:52
Оценка за ответ: 5
Комментарий оценки:
Спасибо.

Отвечает: Esi
Здравствуйте, Миленин Александр!
Для этого нужно:
SELECT 0 as prizn_free, COUNT(DISTINCT `ip`) AS `num` FROM `lan` WHERE `free`='0'
union all
SELECT 1 as prizn_free, COUNT(DISTINCT `ip`) AS `num` FROM `lan` WHERE `free`='1'
order by prizn_free
Это один из вариантов.

Удачи!
Ответ отправил: Esi (статус: 3-ий класс)
Ответ отправлен: 21.02.2008, 06:39
Оценка за ответ: 5
Комментарий оценки:
Спасибо.

Отвечает: Силантьев А.В.
Здравствуйте, Миленин Александр!
Присоединяюсь к ответу Raptor,
но только ко второй его части.
Первая часть ответа не подходит.
Итак:
select free as `type`, count(distinct(ip)) AS `num`
from lan where free=0 or free=1
group by free
Ответ отправил: Силантьев А.В. (статус: 1-ый класс)
Ответ отправлен: 21.02.2008, 08:52
Оценка за ответ: 5
Комментарий оценки:
Спасибо за помощь!

Отвечает: Sergey T
Здравствуйте, Миленин Александр!

Вообще нет особой разницы, что именно использовать - UNION или GROUP BY.
Только например с GROUP BY можно вернуть количество уникальных IP по всем free, которые имеются в таблице. Но если бы мне нужно было толко по двум значениям - я бы наверно воспользовался объединением.

Вот еще несколько вариантов:

- возвращаем количество уникальных IP по всем имеющимся значениям FREE (с сортировкой по FREE)

SELECT 'free', COUNT(DISTINCT('ip')) AS 'num'
FROM 'lan'
GROUP BY 'free'
ORDER BY 'free'

- то же самое, только уже с условием по нужным FREE

SELECT 'free', COUNT(DISTINCT('ip')) AS 'num'
FROM 'lan'
WHERE 'free' IN (0, 1) -- тут перечисляем через запятую все нужные нам FREE
GROUP BY 'free'
ORDER BY 'free'

- с использованием объединения все аналогично ответу ESI, правда можно без ALL, так как значения FREE мы уже ставим уникальные. Но это уже как кому приятнее.

Удачи.
Ответ отправил: Sergey T (статус: 1-ый класс)
Ответ отправлен: 21.02.2008, 09:39
Оценка за ответ: 5
Комментарий оценки:
Спасибо за ответ и обьяснения, мне очень помогло.

Отвечает: Zinaida
Здравствуйте, Миленин Александр!Такой запрос можно модифицировать так:
SELECT COUNT(DISTINCT `ip`) AS `num` FROM `lan` WHERE `free`='0'
UNION
SELECT COUNT(DISTINCT `ip`) AS `num` FROM `lan` WHERE `free`='1'
Можно так:
select distinct 'ip', count(*) from 'lan'
where `free`='0' or `free`='1'
group by 'ip'
Ответ отправила: Zinaida (статус: 1-ый класс)
Ответ отправлен: 21.02.2008, 10:31
Оценка за ответ: 5
Комментарий оценки:
Спасибо, пользуюсь первым вариантом, во втором видимо проблемы с ковычками.

Отвечает: Синельников Сергей
Здравствуйте, Миленин Александр!

Смею предположить, что из одной записи более удобно получать результаты. А по сему вот:

SELECT COUNT(DISTINCT `ip`*`free`)-1 AS `numfree1`, COUNT(DISTINCT `ip`*(`free`-1))-1 AS `numfree0`FROM `lan` WHERE `free`=0 OR `free`=1

В первом столбце будет для free=1, во втором для free=0
Ответ отправил: Синельников Сергей (статус: 4-ый класс)
Ответ отправлен: 25.02.2008, 21:25
Оценка за ответ: 4
Комментарий оценки:
Спасибо, идея очень хорошая, но видимо в реализации ошибка, оба значения всегда равны единице.


Вопрос № 124.216
Здравствуйте. Есть оборудование, которое периодически включается и выключается. Данные о статусе оборудования заносятся в таблицу, в которой поля - id(номер оборудования), datestatus(дата изменения статуса), status(1-включили, 0-выключили). То есть id может повторяться. И есть таблица с выборкой номеров оборудования. Вопрос: каким запросом получить состояние оборудования из второй таблицы на текущий момент? То есть нужно взять id из второй таблицы, найти все записи в первой таблицы с этим id и затем найти запись с наибольшей датой, и поле status покажет статус оборудования на текущий момент. Результат запроса нужно поместить в табличку с полями - id, status. Вот запрос правильный я и не могу никак составить. БД - MSSQL 2000
Отправлен: 21.02.2008, 13:35
Вопрос задал: Рыбин Павел (статус: 4-ый класс)
Всего ответов: 4
Мини-форум вопроса >>> (сообщений: 1)

Отвечает: Челноков Виктор Альбертович
Здравствуйте, Рыбин Павел!

select top (1) id,status from tabl where id=3
order by datestatus desc

Выполните такой запрос.
Вместо 3 подставте номер оборудования какой Вам нужен.
Ответ отправил: Челноков Виктор Альбертович (статус: 6-ой класс)
Ответ отправлен: 21.02.2008, 13:47
Оценка за ответ: 3

Отвечает: Коровин Александр
Здравствуйте, Рыбин Павел!
Попробуете такой запрос

SELECT t2.id, t1.st
FROM table2 t2
INNER JOIN (SELECT top 1 id, st
FROM table1
WHERE id='1'
ORDER BY data DESC) t1 ON t1.id=t2.id
Ответ отправил: Коровин Александр (статус: 2-ой класс)
Ответ отправлен: 21.02.2008, 14:15

Отвечает: Силантьев А.В.
Здравствуйте, Рыбин Павел!

Если Вы указываете на конкретный Id и хотите произвести запись в третью таблицу именно по этому Id, а из второй таблицы кроме этого Id больше
ничего не требуется, то можно обратиться сразу к первой таблице и тогда:
insert into t3(id,status)
select t11.id, t11.status
from t1 t11
where t11.id=:id
and t11.datestatus in (select max(datestatus) from t1 t12 where t12.id=:id);
Ответ отправил: Силантьев А.В. (статус: 1-ый класс)
Ответ отправлен: 21.02.2008, 15:58

Отвечает: Sergey T
Здравствуйте, Рыбин Павел!

Данную задачу решить довольно просто тремя способами.
Давайте для начала определимся с нашими таблицами:
Device(id) - это таблица с id устройств,
DeviceStatus(id, datestatus, status) - это таблица, куда пишутся состояния устройств,
RetTable(id, status) - наша таблица.

Первый вариант соответствует стандарту SQL-92 и должен (но не обязан) выполняться на любой платформе БД.
Второй и третий варианты будут работать скорее всего только на SQL SERVER 2000.
Первый на нем тоже будет работать, но я думаю, что 2 и 3 будут предпочтительнее и менее нагрузят сервер при их обработке.
Но это только мои мысли и предположения - в реальности надо тестировать и смотреть.
Да и от размера БД и ее индексации и прочего многое зависит. Но в общем я отвлекся...

Итак! Варианты.

Вариант 1:

INSERT INTO RetTable(id, status)
SELECT d.id, (SELECT s.status FROM DeviceStatus s
WHERE s.id=d.id
AND s.datestatus=(SELECT MAX(w.datestatus) FROM DeviceStatus w
WHERE w.id=s.id))
FROM Device d
ORDER BY d.id

Вариант 2:

INSERT INTO RetTable(id, status)
SELECT d.id, f.status
FROM Device d (NOLOCK)
LEFT JOIN (SELECT s.id, s.status FROM DeviceStatus s (NOLOCK)
WHERE s.datestatus=(SELECT MAX(w.datestatus)
FROM DeviceStatus w (NOLOCK) WHERE w.id=s.id)) f
ON d.id=f.id
ORDER BY d.id

Вариант 3:

INSERT INTO RetTable(id, status)
SELECT d.id, f.status
FROM Device d (NOLOCK)
LEFT JOIN (SELECT s.id, s.status FROM DeviceStatus s (NOLOCK)
INNER JOIN (SELECT id, MAX(datestatus) AS 'datestatus'
FROM DeviceStatus (NOLOCK) GROUP BY id) w
ON s.id=w.id AND s.datestatus=w.datestatus) f
ON d.id=f.id
ORDER BY d.id

Примечание:
Если вам не нужны устройства, по которым нет данных о их состоянии - то во 2 и 3 варианте вместо LEFT JOIN используйте RIGHT JOIN. Работать будет быстрее.
В первом варианте такого сделать нельзя, если конечно в условии не продублировать секцию SELECT - но проще просто удалить потом.

Удачи.
Ответ отправил: Sergey T (статус: 1-ый класс)
Ответ отправлен: 22.02.2008, 14:08


Вы имеете возможность оценить этот выпуск рассылки.
Нам очень важно Ваше мнение!
Оценить этот выпуск рассылки >>

Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2008, Портал RusFAQ.ru, Россия, Москва.
Авторское право: ООО "Мастер-Эксперт Про"
Техподдержка портала, тел.: +7 (926) 535-23-31
Хостинг: "Московский хостер"
Поддержка: "Московский дизайнер"
Авторские права | Реклама на портале
Версия системы: 4.70 от 17.01.2008
Яндекс Rambler's Top100
RusFAQ.ru | MosHoster.ru | MosDesigner.ru | RusIRC.ru
Kalashnikoff.ru | RadioLeader.ru | RusFUCK.ru

В избранное