Jump to content
php.lv forumi

Saskaitīt unikālus ierakstus konkrētā dienā


AnotherUser

Recommended Posts

Sveiki, meklēju effektivāku/ātrāku risinājumu..

Tabulas lauki:
 

+----+-----+------+---------------+
| ID | uId | hits | date_hour     |
+----+-----+------+---------------+
|  1 | 101 |    2 | 2013-12-01 13 |
|  2 | 101 |    5 | 2013-12-01 14 |
|  3 | 101 |    1 | 2013-12-01 15 |
|  4 | 102 |    3 | 2013-12-01 15 |
|  5 | 102 |    1 | 2013-12-02 16 |
|  6 | 103 |    9 | 2013-12-02 17 |
|  7 | 104 |    4 | 2013-12-02 17 |
|  8 | 105 |    2 | 2013-12-03 02 |
|  9 | 106 |    1 | 2013-12-03 10 |
| 10 | 107 |    1 | 2013-12-03 12 |
+----+-----+------+---------------+

Nepieciešams saskaitīt cik unikālie (pa visu laiku) `uId` ir konkrētā dienā, respektīvi no šiem datiem rezultāts būtu sekojoš:
 

2013-12-01  2(unikālie)
2013-12-02  2(unikālie)
2013-12-03  3(unikālie)

Dotajā brīdī atlasu šādi:
 

SELECT COUNT(DISTINCT `uId`) as uniq
FROM `table` as ts
WHERE (SELECT DATE(ts2.`date_hour`)
        FROM `table` as ts2
        WHERE ts.uId = ts2.uId
        ORDER BY ts2.`id`
        LIMIT 1) = :date
AND DATE(ts.`date_hour`) = :date

Paldies.

Edited by AnotherUser
Link to comment
Share on other sites

  • Replies 35
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

1. Ja tu domāji ar substr izvilkt 'gads-mēnesis-diena', tad jāsāk no 1. pozīcijas.

2. Prikškam izmantot substr + date() ? Dubults neplīst?

3. Dotajs piemērs atlasīs vairākus ierakstus (tik cik unikālie datumi), jo tiek grupēts pēc datuma un noteikti ne-unikālos `uId`

4. Mēģināšu vēlreiz izskaidrot:

 

Tātad nepieciešams saskaitīt unikālos `uId` - tā lai rezultātā man atgriež vienu ierakstu (par konkrēto datumu, kuru es pieprasu) ar skaitu cik unikalie, tajā datumā iekrita.

Unikalais - unikāls `uId` pa visu tabulu(visām dienam), respektīvi ja tabulā eksistē ieraksts ar `uId` - 101, tad tas ir viens unikals ieraksts un citās dienās/mēnešos/gados, mēs viņu vairs neuzskatam par unikalu.

 

Mans piemērs darbojas no loģiskā viedokļa perfekti, bet neapmierina pats tehniskais izpildījums/ātrdarbība, šķiet jābūt kādam elegantākam risinājumam.

Edited by AnotherUser
Link to comment
Share on other sites

Unikalais - unikāls `uId` pa visu tabulu(visām dienam), respektīvi ja tabulā eksistē ieraksts ar `uId` - 101, tad tas ir viens unikals ieraksts un citās dienās/mēnešos/gados, mēs viņu vairs neuzskatam par unikalu.

 

 

Nezinu, varbūt es kaut ko nesaprotu, bet vai šādi nestrādātu:

SELECT COUNT(DISTINCT `uId`)
FROM `table`
WHERE DATE(`date_hour`) = :date
?

 

 

Šādi tu dabūsi unikalos tikai tā datuma ietvaros, bet tāds `uId` varbūt jau ir bijis vakar vai gadu atpakaļ ierakstījies..

Edited by AnotherUser
Link to comment
Share on other sites

Briedi, ņemot tavu domu gājienu par pamatu, manā situācijā tas izskatās sekojoši:

SELECT SUM(dd.`uniq`) as uniq 
FROM (SELECT COUNT(d.`date_hour`) as uniq 
      FROM (SELECT `date_hour` 
	    FROM `table` 
	    WHERE DATE(`date_hour`) = :date
	    GROUP BY `uId`) AS d 
      GROUP BY d.`date_hour`) as dd

..Izpildās 1/3 ilgāk..

 

Vēl varianti?

Link to comment
Share on other sites

Var!

SELECT COUNT(DISTINCT `uId`) as uniq
FROM `table` as ts 
WHERE ts.`uId` NOT IN (SELECT ts2.`uId` FROM `table` as ts2 WHERE ts2.`date_hour` != ts.`date_hour`) AND DATE(ts.`date_hour`) = '2013-12-15'

Respektīvi kad man tabulā būs 1M ierakstu, iekš NOT IN (būs 1M id'u..), Neder..

 

Nu kur ir mūsu LV, DB Gurū..?

Edited by AnotherUser
Link to comment
Share on other sites

Nū, ja problēma ir ātrdarbība, tad ir jādomā par indeksiem. Bet tīklīdz tu sāc taisīt prikolus ar funkcijām uz kolonnām (DATE()), tā var aizmirst, ka tur kaut kas jēdzīgā laikā izpildīsies, jo jāiet cauri būs pilnīgi visiem ierakstiem.

 

Neesmu baigais specs, bet pamēģini gan to subselektu, gan arī galveno selektu izpētīt ar EXPLAIN un pielāgot tabulu, lai pilnībā tiktu izmantoti indeksi. Minu, ka arī vajadzēs glabāt tikai datumu atsevišķā kolonnā, lai var normāli grupēt.

Link to comment
Share on other sites

Un neaizmirsti noindexēt:

CREATE TABLE
    `test2`
(
    id serial primary key
    , uid int
    , hits int
    , date_hour datetime
);

INSERT INTO
    `test2`
(
    uid
    , hits
    , date_hour
)
VALUES
    ( 101, 2, '2013-12-01 13' )
    , ( 101, 5, '2013-12-01 14' )
    , ( 101, 1, '2013-12-01 15' )
    , ( 102, 3, '2013-12-01 15' )
    , ( 102, 1, '2013-12-02 16' )
    , ( 103, 9, '2013-12-02 17' )
    , ( 104, 4, '2013-12-02 17' )
    , ( 105, 2, '2013-12-03 02' )
    , ( 106, 1, '2013-12-03 10' )
    , ( 107, 1, '2013-12-03 12' );
    
SELECT
  date( date_hour )
  , count( distinct uid )
FROM
  `test2`
GROUP BY
  date( date_hour )
ORDER BY
  date_hour ASC;

SQL Fiddle

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...