Do Subselects make SQlite ignore distincts? - database

we are facing a strange behaviour in SQLite (Version 3).
We have a table for Vehicles with two columns referencing an engine and a gear.
Of course there could be more than one vehicle with the same engine gear combination.
I now want to find the distinct combination of engines and gears of the vehicles (and use it for an insert => thats why randomblob(36)).
Example:
Vehicle | EngineId | GearId
-----------------------------
1 | 1 | 1
1 | 1 | 2
1 | 2 | 1
1 | 2 | 2
1 | 1 | 2
1 | 1 | 2
The following select statement results in too many rows:
Select randomblob(36), tmp.EngineId, tmp.GearId from (Select distinct EngineId, GearId from tblVehicle order by EngineId, GearId) as tmp;
RandomId| EngineId | GearId
-----------------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 2 | 2
5 | 1 | 2
6 | 1 | 2
But the expected result would just be:
RandomId| EngineId | GearId
-----------------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 2 | 2
If I replace the randomblob(36) with a constant, the result is as expected (of course without a random Id).
Select 2, tmp.EngineId, tmp.GearId from (Select distinct EngineId, GearId from tblVehicle order by EngineId, GearId) as tmp;
Can someone explain me this behaviour of SQLite? Is this the expected behaviour?

This is a bug.
I can reproduce this with SQLite 3.6.23.1 but not with 3.7.15, so it has been fixed already.

Related

SQL Server: Flag only First duplicate row

I want to flag only the first duplicate ID-VL combination in the dataset shown below. Column FirstOccurence is what I want the end result to be.
ID VL FirstOccurence
1 a 1
1 b 1
2 a 1
2 a 0
3 a 1
3 a 0
4 a 1
4 a 0
5 a 1
5 b 1
5 a 0
There is currently not a unique index available in the original table.
Is there any way to do this with for instance the LAG-functionality? I cannot find any examples online that result in the flagging of duplicates. Any suggestions are much appreciated!
Kind regards,
Igor
One method is with ROW_NUMBER() along with a CASE expression:
SELECT
ID
,VL
,CASE ROW_NUMBER() OVER(PARTITION BY ID, VL ORDER BY ID, VL) WHEN 1 THEN 1 ELSE 0 END AS FirstOccurance
FROM dbo.example
ORDER BY
ID
,VL
,FirstOccurance;
Results:
+----+----+----------------+
| ID | VL | FirstOccurance |
+----+----+----------------+
| 1 | a | 1 |
| 1 | b | 1 |
| 2 | a | 0 |
| 2 | a | 1 |
| 3 | a | 0 |
| 3 | a | 1 |
| 4 | a | 0 |
| 4 | a | 1 |
| 5 | a | 0 |
| 5 | a | 1 |
| 5 | b | 1 |
+----+----+----------------+
Note that this result order differs from your end result. If there are one or more columns present in the table that provide the same ordering as the results in you question, specify that in the ORDER BY clause instead.

Getting Extra Rows when trying to join to of the same table when creating a view

We have a table that gets data imported into it from an Excel file.
I am creating a view from that table, joining the table on itself, and adding a rownumber column. Unfortunately I get two extra rows when I run the sql statement and I can't figure out how to get rid of them or if there is a better solution for adding the rownumber/join the tables.
The original table has a row for each candidate yes and no. I tried to join them so yes and no show up in the same row for the precinct / contest.
SELECT CAST(ROW_NUMBER() OVER (ORDER BY
(SELECT 1)) AS INT) AS ID, t .*
FROM (SELECT DISTINCT
a.PRECINCT_NAME,
a.CONTEST_FULL_NAME,
CAST(a.BALLOT_CAST AS INT) AS 'BALLOT_CAST',
a.CANDIDATE_FULL_NAME AS 'CANDIDATE_1',
a.PARTY_CODE AS 'PARTY_CODE_1',
CAST(a.VOTE_COUNT AS INT) AS 'VOTECOUNT_1',
b.CANDIDATE_FULL_NAME AS 'CANDIDATE_2',
b.PARTY_CODE AS 'PARTY_CODE_2',
CAST(b.VOTE_COUNT AS INT) AS 'VOTECOUNT_2'
FROM dbo.Election_Special a
JOIN dbo.Election_Special b
ON a.PRECINCT_NAME = b.PRECINCT_NAME
WHERE
(a.CANDIDATE_FULL_NAME = 'Yes') AND (b.CANDIDATE_FULL_NAME = 'No')
) AS t
Actual Output:
PRECINCT NAME | CONTEST FULL NAME | CANDIDATE 1 | VOTE 1 | CANDIDATE 2 | VOTE 2
PRECINCT 1 | CONTEST 1 | YES | 3 | NO | 3
PRECINCT 2 | CONTEST 2 | YES | 6 | NO | 4
PRECINCT 3 | CONTEST 3 | YES | 7 | NO | 5
PRECINCT 4 | CONTEST 1 | YES | 1 | NO | 7
PRECINCT 4 | CONTEST 2 | YES | 6 | NO | 1
PRECINCT 4 | CONTEST 1 | YES | 0 | NO | 0
PRECINCT 4 | CONTEST 2 | YES | 0 | NO | 0
PRECINCT 5 | CONTEST 3 | YES | 3 | NO | 4
Expected OutPut
PRECINCT NAME | CONTEST FULL NAME | CANDIDATE 1 | VOTE 1 | CANDIDATE 2 | VOTE 2
PRECINCT 1 | CONTEST 1 | YES | 3 | NO | 3
PRECINCT 2 | CONTEST 2 | YES | 6 | NO | 4
PRECINCT 3 | CONTEST 3 | YES | 7 | NO | 5
PRECINCT 4 | CONTEST 1 | YES | 1 | NO | 7
PRECINCT 4 | CONTEST 2 | YES | 6 | NO | 1
PRECINCT 5 | CONTEST 3 | YES | 3 | NO | 4
At the moment you are "exploding" your data. 1 row becomes 2.
you need to figure out what the "natural key" of your table is - ie the columns that give 1 row per combination.
i think it is PRECINCT NAME & CONTEST FULL NAME
so you can test this with a group by/having...
select PRECINCT NAME , CONTEST FULL NAME
from election_special
group by
PRECINCT NAME , CONTEST FULL NAME
having count(*) > 1
if this returns 0 records then you are all set and you can just add this column to your self-join
eg:
ON a.PRECINCT_NAME = b.PRECINCT_NAME
and a.CONTEST_FULL_NAME = b.CONTEST_FULL_NAME

Can't build click house query

I have a click house table like this:
page_id ad_id date
-------|-------|------------|
1 | 10 | 04/03/2009 |
1 | 2 | 04/03/2009 |
1 | 2 | 04/03/2009 |
1 | 4 | 04/03/2009 |
1 | 2 | 04/03/2009 |
2 | 1 | 04/03/2009 |
2 | 5 | 04/03/2009 |
3 | 2 | 04/03/2009 |
3 | 2 | 04/03/2009 |
3 | 2 | 04/03/2009 |
3 | 8 | 04/03/2009 |
4 | 1 | 04/03/2009 |
4 | 1 | 04/03/2009 |
5 | 2 | 04/03/2009 |
This table contains the history of clicks on different ad-blocks on different pages. Just a big log. I want to get top ads with hits count for each page. Smthing like
page_id ad_id hits
-------|-------|------------|
1 | 2 | 3 |
2 | 1 | 1 |
3 | 2 | 3 |
4 | 1 | 2 |
5 | 2 | 1 |
Hope somebody can help me. Thanks.
Try this:
SELECT page_id, ad_id, count() cnt
FROM TABLE_NAME
GROUP BY page_id, ad_id
ORDER BY page_id, cnt DESC
LIMIT 1 BY page_id
Link to doc
There is one more solution with approximate calculations that can give an incompletely accurate result, but quickly (the number of hits can be counted through a subquery)
SELECT page_id, topK(1)(ad_id) ad_id
FROM table_name
GROUP BY page_id

Insert all combinations of two tables in intermediate table in SQL Server

My situation
I'm making a site where people can reserve meeting rooms. On the reservation form for a meeting room, I've some optional field sets like below:
ID | Name
-- | ------------
1 | Catering
2 | Coffee break
3 | Drinks
Here are some example meeting rooms:
ID | Name | Location
-- | ------- | ---------
1 | Dog | Brussel
2 | Cat | Antwerpen
3 | Chicken | Brugge
4 | Cow | Gent
I'm using Microsoft SQL server 2016.
Database structure
The fieldsets from the first code block stands inside my database in the table reservationFieldsets.
The meeting rooms stands in the meetingRooms table.
There is an intermediate table named meetingRoomsReservationFieldsets.
Question
Now I'll fill meetingRoomsReservationFieldsets with all rooms and all the fieldsets like below:
RoomID | FieldsetID
------ | ----------
1 | 1
2 | 1
3 | 1
4 | 1
1 | 2
2 | 2
3 | 2
4 | 2
1 | 3
2 | 3
3 | 3
4 | 3
I've tried
I've tried to do it manually but there are a lot of rooms and too much to do that manual.
I've found it by the comments on the question. I use this code:
INSERT INTO meetingRoomsReservationFieldsets
SELECT meetingRooms.id, reservationFieldsets.id
FROM reservationFieldsets
CROSS JOIN meetingRooms

Segregate every second group into 1 or 2 groups SQL

I have a list of multiple components that all have a model number. I want to group every second component based on the model it belongs to.
Model | Component | Group
1 1 1
1 2 2
1 3 1
1 4 2
1 5 1
2 1 1
2 2 2
2 3 1
Every second component belonging to a model should have an alternative group number.
I believe I have to use a windows function but haven't been able to solve.
I have assumed that your Model and Component ID numbers will not be perfectly incremental, but that they will be unique. As such, you can use the row_number windowed function along with the modulo operator % to get the remainder of the division of the row_number result by 2:
declare #t table (Model int, Component int);
insert into #t values (1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,2),(2,2);
select Model
,Component
,case (row_number() over (partition by Model order by Component) % 2)
when 1 then 1
when 0 then 2
end as [Group]
from #t;
Output:
+-------+-----------+-------+
| Model | Component | Group |
+-------+-----------+-------+
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| 1 | 3 | 1 |
| 1 | 4 | 2 |
| 1 | 5 | 1 |
| 2 | 1 | 1 |
| 2 | 2 | 2 |
| 2 | 2 | 1 |
+-------+-----------+-------+

Resources