Автор Тема: MySQL - резултат от SELECT, променящ се в зависимост от стойност в друга таблица  (Прочетена 6293 пъти)

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
В таблица settings имам IgnoreTime, което е 0 или 1:
Цитат
CREATE TABLE `settings` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` char(16) NOT NULL,
  `value` tinyint(3) unsigned NOT NULL,
  PRIMARY KEY (`ID`)
);

INSERT INTO settings (name, value) VALUES ('IgnoreTime', 1);

Клиентът не знае за съществуването на тази таблица.

В друга таблица имам поле Time (Time). Искам при SELECT от тази таблица, когато ignoreTime в settings е 0, във WHERE да има "... and Time='13:00:00' ..." напр., а когато е 1 това условие да липсва.

Как да го направя?

В момента имам два изгледа. В единия го има, а в другия - не и в зависимост от това, дали искам Time да се проверява или не, преименовам изгледите. Искам да го направя автоматизирано с промяната на ignoreTime.
« Последна редакция: Oct 13, 2017, 16:29 от laskov »
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

Naka

  • Напреднали
  • *****
  • Публикации: 3395
    • Профил
Дали съм разбрал???


AND ( ! IgnoreTime OR (Time='13:00:00') )


Ако IgnoreTime е 0 Целият израз се свежда до

AND (! 0 OR ......) = AND (1 OR ...) = AND 1

Понеже се Свежда до AND 1 в резултатното куери този остатъчен израз няма да влияе на другите условия ако ги има. - т.е. Все едно че го няма. Но трябва да е накрая.
... WHERE ...AND... OR.....AND .. AND 1

Ако IgnoreTime е 1 израза става:

AND (! 1 OR Time='13:00:00' ) = AND (0 OR Time='13:00:00') = AND (Time='13:00:00')
т.е. така почва да влияе втората част Time='13:00:00'

С подобно нещо се мъчих и аз....Но да се осъзнае [_]3 трябва да се разпише таблицата на истиност. Много е завъртяно......

------
ПС: Сега видях че искаш обратното Тогава израза става:
AND ( IgnoreTime OR (Time='13:00:00') )


Както и да е горното няма да го редактирам. Горното Има смисъл на флаг (AllowTime) оставям го на някой може да му послужи или ако случайно решиш да обърнеш флага.


« Последна редакция: Oct 13, 2017, 16:15 от Naka »
Активен

Perl - the only language that looks the same before and after encryption.

remotexx

  • Напреднали
  • *****
  • Публикации: 3210
    • Профил
Колеги има по прост вариант, но колегата малко ме подведе първоначално та се омотах и аз.
Колега друг път моля да пояснявате какво имате предвид под „имам” аз..бая време мислех че е име на поле в таблицата, а то било стойност на полето, Ами като такава пък било то и символен низ, слагайте го в кавички при вкарване. .

Значи понеже са две таблиците и в един момент може да се разсинхронизират, желателно е да се ползва join или пък подзаявка, което ви е по лесно..
 Напр. със join

Select a.*, if(coalesce(b.value,0) = 1, a.IgnoreTime, null) as mytime
From xxx a left join yyy b on someID and value='IgnoreTime'
Where ...


Внимание не си мислете че полето никога не може да е null, щото сте указали not null
Напр. Дори и да ползвате транзакциите ако администратора на БД е настроил да се ползва т нар. Dirty read тогава може да попаднете в ситуация когато едната таблица е вече обновена а другата още не и тогава left join ще върне null - та нашата си там стойността коеято искате да ви връща при null във coalesce оператора
« Последна редакция: Oct 13, 2017, 16:21 от remotexx »
Активен

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
1. И аз си мислех за това как да ги свържа с JOIN - те нямат нищо общо.
2. Не съм си и представял, че
Цитат
SELECT ID FROM `main` WHERE `date`=curdate() and ((SELECT value from nastroiki where name='IgnoreTime') OR `time`='13:00:00');
може да работи! А то май работи! :)  [_]3

А правилно ли е? Имам предвид не дали ще ми върши работа, а дали е коректно да се ползва така.
« Последна редакция: Oct 13, 2017, 16:40 от laskov »
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
... слагайте го в кавички при вкарване.
Извинявайте за пропуска!
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

remotexx

  • Напреднали
  • *****
  • Публикации: 3210
    • Профил
Извинявам се, аз не съм разбрал правилно постановката - даже и от втория прочит (ама защото се разсеях малко с това IgnoreTime поле ли е или стойност)

значи (поправете ме ако греша, но) таблицата с настройките е една единствена и в нея има един единствен ред който да е приложим за цялата друга таблица т.е. JOIN вече не върши работа

нека колегата ме поправи ако греша, но първото което ми идва наум в момента е (т.е. преносимия или правилния вариант - не знам що неогвото работи, но май няма да е поратбъл - МъСЯЛ изврашения някакви - правилното е да се ползва EXISTS)

Код
GeSHi (SQL):
  1. SELECT ID
  2.  FROM `main`
  3.  WHERE `date`=curdate()
  4.    AND ( EXISTS(SELECT 1 FROM nastroiki WHERE name='IgnoreTime' AND value=1) OR `time`='13:00:00' )
  5.  

- скобите са важни т.е. когато IgnoreTime=TRUE това в скобите винаги е вярно и WHERE (о)става WHERE `date`=curdate() AND (TRUE), а когато IgnoreTime=FALSE вече ще се наложи дасе оценя и второто условие дали е вярно `time`='13:00:00'

П.П. Предполагам твоето няма да работи ако вътрешния SELECT върне NULL т.е. ако въобще няма такъв запис в settings и ще ти заNULL-и и времето а обик и всичко останало ;-) в такива сл. обик. се прибягва до EXISTS където NULL вече е еквивалентно на NOT EXISTS / FALSE
извинявам се предварително ако отново не съм уцелил заявката - нямам къде да пробвам (mySQL)
« Последна редакция: Oct 13, 2017, 20:24 от remotexx »
Активен

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

Naka

  • Напреднали
  • *****
  • Публикации: 3395
    • Профил
За предпазване от НУЛЛ стойности, може да се ползва и IFNULL()

IFNULL(1,0) -> 1
IFNULL(0,0) -> 0
IFNULL(NULL,0) -> 0

Така дали би станало?
IFNULL( (SELECT value from nastroiki where name='IgnoreTime'), 0)

Но всичко това отпада ако има такъв запис и е 100% сигурно, че саб куерито няма да върне NULL.


Друго си мислех, Няма ли да е по удобно и разбирамо с две куерита:
1. Първото куери да сетне променлива @IgnoreTime според 'settings' таблицата. Но незнам как точно става. В това куери може да се включат IFNULL() или EXISTS() така че да е сигурно, че даже и да няма резултат  @IgnoreTime винаги да има само стойности 0, 1
Мисля си, че това е много по добър варянт, щото това все пак са флагове (сетинги) и много по добре се пасват на променливи.

2. а второто куери вече да я ползва, където и колкото си иска.
SELECT ID FROM `main` WHERE `date`=curdate() and (@IgnoreTime OR `time`='13:00:00');

« Последна редакция: Oct 14, 2017, 16:11 от Naka »
Активен

Perl - the only language that looks the same before and after encryption.

remotexx

  • Напреднали
  • *****
  • Публикации: 3210
    • Профил
Значи IFNULL не е част то ANSI SQL стандрта, там има само XXX IS NULL, обаче това е най-малкия дерт... както казах и преди неправилно е да се ползва на доверие и щото в един частен случай работи, защото в най-общия случай SELECT връща по повече от един ред и тогава това IFNULL, че даже и ... IS NULL кой точно ред ще оценява?
- както казах и преди в стандарта съществува EXISTS точно за такива случаи - връща TRUE/FALSE и даже и да им повече от един ред пак връща едно единствено TRUE, плюс това работи и ако върне NULL това е еквивалентно на NOT EXISTS

- с две заявки (без подзаявка) мисля че няма да стане ..защото колегата не спомена ама вероятно ползва някакви ГУИ контроли които не могат да работят с повече от една заявка (защото беше споменал че правил с изглед и сменял изгледа, предполагам точно по тази причина иначе щеше да си го направи там с 3-4 заявки и хич нямаше да пита тъдява...)
Активен

Naka

  • Напреднали
  • *****
  • Публикации: 3395
    • Профил
Това ме подсеща че в таблицата 'settings' трябва да има Уикален Ключ по 'name'. А той има само по ID.

След като това е конфигурационна опция, няма как да има два реда с едни и същи сетинги.
Тогава куерито няма как да му върне >1 ред, щото няма да се допусне изобщо да се въведе дублираща информация.
Активен

Perl - the only language that looks the same before and after encryption.

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
...
Но всичко това отпада ако има такъв запис и е 100% сигурно, че саб куерито няма да върне NULL.
Амии... 100% трябва да има такъв запис.

Друго си мислех, Няма ли да е по удобно и разбирамо с две куерита:
1. Първото куери да сетне променлива @IgnoreTime според 'settings' таблицата.
...
Май няма да ми хареса, понеже IgnoreTime може да се промени (теоретично) във всеки момент.

... някакви ГУИ контроли които не могат да работят с повече от една заявка (защото беше споменал че правил с изглед и сменял изгледа, предполагам точно по тази причина иначе щеше да си го направи там с 3-4 заявки и хич нямаше да пита тъдява...)
Не е ГУИ :) . 6 устройства питат и с тогавашните ми знания не можах да измисля по-добър вариант - мога да променям изгледа и да не бърникам програмите на устройствата. А от IgnoreTime освен тези 6, в момента зависят и още 3 устройства с перспектива броят им да се увеличи.
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
You can only select  local files.
Настройка на програми
HarleyBG 0 1586 Последна публикация Sep 22, 2005, 00:37
от HarleyBG
You can only select local files!
Хардуерни и софтуерни проблеми
HarleyBG 6 3420 Последна публикация Sep 22, 2005, 22:39
от HarleyBG
Специфична sql заявка - select + join
Web development
thc 4 5108 Последна публикация Oct 27, 2006, 19:38
от thc
Mysql: can't connect to local mysql server
Настройка на програми
wonder 1 5137 Последна публикация Mar 16, 2008, 01:17
от neter
select от много таблици
Web development
edmon 8 4101 Последна публикация Oct 03, 2014, 23:51
от borovaka