webForumDet fria alternativet

COUNT och DISTINCT, val av unika id:n

Databaser & SQL

6 svar · 321 visningar · startad av psu

Medlem sedan okt. 20025 inlägg
Frågan#1

har ett problem som rör hur man använder DISTINCT tillsammas med COUNT.
Tabellen datum:

id                tid
------------------------------
1                 2002-12-03
2                 2002-12-02
2                 2002-12-04
3                 2002-12-03
3                 2002-12-03
3                 2002-12-01
1                 2002-12-05
1                 2002-12-02
1                 2002-12-03

En lista över hur många unika id:n det finns för varje veckodag (måndag=2,tisdag=1 osv) kan man få med denna frågan:

SELECT WEEKDAY(tid) AS vdag, COUNT(DISTINCT id) FROM datum GROUP BY vdag;

Problemet är att jag inte bara vill att varje id ska vara unikt för varje veckodag, utan ett id ska vara unikt för alla veckodagar.

det borde gå, det måste gå!

--
mvh psu

Medlem sedan dec. 200012 464 inlägg
#2

Vad är problemet?

SELECT WEEKDAY(tid) AS vdag, COUNT(DISTINCT id) FROM datum GROUP BY WEEKDAY(tid)
Medlem sedan okt. 20025 inlägg
#3

problemet är att frågan som jag skrev i inlägget bara ser till att det bara finns unika id i varje grupp (alltså för varje veckdag).
jag vill att ett id bara ska kunna förekomma en enda gång. om det finns med i måndags-gruppen, ska det inte räknas i tisdagsgruppen.

Medlem sedan dec. 200012 464 inlägg
#4

Jaha, var det det du menade.

select weekday(d1.tid),count(distinct d1.id) 
  from datum as d1 left join datum as d2 on
  d1.id = d2.id and weekday(d1.tid) > weekday(d2.tid)
where d2.id is null
group by weekday(d1.tid)

Vill du få fram alla veckodagar, även om det är 0 nya distinkta id för den dagen?

Medlem sedan okt. 20025 inlägg
#5

tack.. det funkar fint.
jo, hade vart fint att få med nollorna också...

jag förstår inte varför "d2.id IS NULL" är med. har du lust att förklara lite???

tack på förhand

--
psu

Medlem sedan dec. 200012 464 inlägg
#6

Anledningen till att man måste använda denna krångliga formulering är att Mysql inte har stöd för subselect.

I vanliga fall skulle man skriva din fråga som

select weekday(tid),count(distinct id)
from datum d1
where id not in (select id from datum where weekday(tid) < weekday(d1.tid))
group by weekday(tid)

Det kan man skriva om med en left outer join, vilket innebär att man får alla rader från den vänstra tabellen oavsett om det finns matchande poster i den högra tabellen. De icke matchande raderna fylls med null i de kolumner som kommer från den högra tabellen. Om man då har ett where villkor på att en kolumn i den högra tabellen skall vara null så blir det samma sak som med not in.

Om du vill ha med nollor så borde det gå att ordna med hjälp av en hjälptabell som innehåller värdena 1-7 som man gör en outer join med.

create table tally(c1 int)

insert into tally values(1),(2),(3),(4),(5),(6),(7)

select weekday(d1.tid),count(distinct d1.id) 
  from tally left outer join datum as d1 
  on c1 = weekday(tid) left join datum as d2 on
  d1.id = d2.id and weekday(d1.tid) > weekday(d2.tid)
where d2.id is null
group by weekday(d1.tid)

otestat

Medlem sedan okt. 20025 inlägg
#7

tack för hjälpen!

det är enklare att "fixa nollorna" i php. (men tack iaf)

--
psu

260 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
123 ms — deklarationer (db)
0 ms — hämta statistik (cache)
134 ms — hämta tråd, inlägg och bilagor (db)
123 ms — ändringar (db)