BG Development


Страници: (5) [1] 2 3 ... последна »  ( Първото ново мнение ) Reply to this topicStart new topicStart Poll

> Помагайте за SQL типов проблем, търся общо решение
johnfound
Публикувано на: 23-08-2018, 08:56
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 6759
Регистриран на: 27.05.04



Напоследък няколко пъти срещам практически един общ проблем в няколко разновидност, но нещо не виждам просто решение. Но аз съм слаб в SQL-а, (както правилно забеляза @Golden Gega), така че помагайте.

Типичен вариант на проблема:
CODE

create table Data (
 id primary key,
 data text
);

create table Users (
 id primary key
);

create table Limits (
 dataID integer references Data(id),
 userID integer references Users(id)
);


Задачата е да се изберат редовете от Data такива че при зададена константа N:

1. или в таблицата Limits да няма нито един ред с dataID за съответния ред от Data
2. или ако има такива редове, то в тях да присъства и ред с userID = N;

Общата идея е, всички да имат достъп до всички записи от Data, а за частните записи до които имат достъп само някои потребители да се правят съответните записи в Limits.

Нещо не мога да измисля достатъчно просто и ефективно решение и всеки път пиша някакви сложни заявки и това ме дразни.


--------------------
asm32 - Приложно програмиране на асемблер.
Tox: 2B446ADCEC7E180CD4C59391D81D4CAB3E99CA7AE767DB3AB45AF976F8A2050FF071DDB733F1
PMEmail PosterUsers Website
Top
deksy
Публикувано на: 23-08-2018, 09:16
Quote Post



Име:
Група: Потребител
Ранг: Новопостъпил

Мнения: 7
Регистриран на: 28.09.15



Не мисля, че си на проблем SQL заявки, защото според мен си все още на проблем approach.
PMEmail PosterUsers Website
Top
Golden Gega
Публикувано на: 23-08-2018, 09:22
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 999
Регистриран на: 04.06.10



Ако съм схванал правилно задачата ще е нещо подобно:

select
d.*
from
Data d left join Limits l on d.id = l.dataID
where
l.userID is null or l.userID = @N

предполага се в Limits да имаш PK(dataID, userID) за производителност и за ограничение по уникалност
PMEmail Poster
Top
johnfound
Публикувано на: 23-08-2018, 09:50
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 6759
Регистриран на: 27.05.04



QUOTE (Golden Gega @ 23-08-2018, 10:22)
Ако съм схванал правилно задачата ще е нещо подобно:

select
d.*
from
Data d left join Limits l on d.id = l.dataID
where
l.userID is null or l.userID = @N

предполага се в Limits да имаш PK(dataID, userID) за производителност и за ограничение по уникалност

Хм, разумно. icon_redface.gif
Втори въпрос тогава. По зададени две константи dataID и userID да се провери дали има достъп до данните, без да се извличат от таблицата Data. Сега го правя така:

CODE
select (select count() from Limits where dataid = ?1 and userid = ?2) > 0 or not exists (select 1 from Limits where dataid = ?1);


Това връща 1 ако има достъп и 0 ако няма. Но прави две заявки до базата. Някакви идеи за по-просто решение?


--------------------
asm32 - Приложно програмиране на асемблер.
Tox: 2B446ADCEC7E180CD4C59391D81D4CAB3E99CA7AE767DB3AB45AF976F8A2050FF071DDB733F1
PMEmail PosterUsers Website
Top
Golden Gega
Публикувано на: 23-08-2018, 10:11
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 999
Регистриран на: 04.06.10



select
count(case when dataID = @1 and userID = @2 then 1 else 0 end),
count(case when dataID = @1 then 1 else 0 end)
from
Limits

ако sql диалекта го позволява, разбира се
PMEmail Poster
Top
johnfound
Публикувано на: 23-08-2018, 10:20
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 6759
Регистриран на: 27.05.04



Диалекта го позволява, но заявката не връща каквото трябва. Най-малкото трябва да връща само една колона. Пък и логиката нещо не ми се връзва. icon_confused.gif


--------------------
asm32 - Приложно програмиране на асемблер.
Tox: 2B446ADCEC7E180CD4C59391D81D4CAB3E99CA7AE767DB3AB45AF976F8A2050FF071DDB733F1
PMEmail PosterUsers Website
Top
Golden Gega
Публикувано на: 23-08-2018, 10:30
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 999
Регистриран на: 04.06.10



Заявката връща две колони, първата е с броя разрешени записи а втория с общия брой записи. Т.е. някъде отзад в кода правиш
if
col1 > 0 // има някакви разрешения за тоя потребител и тая колона
or col2 = 0 // или няма записи за тая колона
then
...
Тоя if може и в sql-а да се направи, но е по-глупав вариант:

CODE
select
 count(case when dataID = @1 and userID = @2 then 1 else 0 end) > 0
 or count(case when dataID = @1 then 1 else 0 end) = 0
from
 Limits
PMEmail Poster
Top
johnfound
Публикувано на: 23-08-2018, 10:42
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 6759
Регистриран на: 27.05.04



QUOTE (Golden Gega @ 23-08-2018, 11:11)
select
  count(case when dataID = @1 and userID = @2 then 1 else 0 end),
  count(case when dataID = @1 then 1 else 0 end)
from
  Limits


Това count() да не е случайно sum()?

Това мнение е било редактирано от johnfound на 23-08-2018, 10:43


--------------------
asm32 - Приложно програмиране на асемблер.
Tox: 2B446ADCEC7E180CD4C59391D81D4CAB3E99CA7AE767DB3AB45AF976F8A2050FF071DDB733F1
PMEmail PosterUsers Website
Top
Golden Gega
Публикувано на: 23-08-2018, 10:46
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 999
Регистриран на: 04.06.10



QUOTE (johnfound @ 23-08-2018, 10:42)
QUOTE (Golden Gega @ 23-08-2018, 11:11)
select
  count(case when dataID = @1 and userID = @2 then 1 else 0 end),
  count(case when dataID = @1 then 1 else 0 end)
from
  Limits


Това count() да не е случайно sum()?

Ох, да, sum() е, извинявай, просто пиша малко наизуст а и малко набързо icon_cool.gif Щото знам че ще го тестваш професионално icon_razz.gif
PMEmail Poster
Top
thrawn
Публикувано на: 23-08-2018, 10:49
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1814
Регистриран на: 17.01.17



Когато искаш само да провериш дали дадено условие е изпълнено се ползва select 1 from ... where ...
Така получаваш отговор само ако условието е изпълнено
PMEmail Poster
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Страници: (5) [1] 2 3 ... последна » Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2018 | BG Development | All Rights Reserved
RSS 2.0