[sqlite] CTE for a noob

2016-03-09 Thread R Smith


On 2016/03/09 10:01 PM, David Raymond wrote:
> For my own clarification, the statements quoted way down below aren't exactly 
> equivalent, correct?
>
> "For each pair of columns identified by a USING clause, the column from the 
> right-hand dataset is omitted from the joined dataset. This is the only 
> difference between a USING clause and its equivalent ON constraint."
>
> (Short version: USING will return fewer fields than ON, and order can matter 
> for both types because of affinity/collation)

Indeed so - the USING optimises the columns out that are coincidental 
(by assuming duplication would be unwanted) when you request the 
asterisk column wildcard, as I did in the examples. I should have been 
more specific in that it is the result-set that is algebraically equivalent.

This per-chance column layout should however never be depended on, 
always specify the columns that you want in the results in any 
production query.


Thanks, good to point this out to prospective USING users!  :)

Cheers,
Ryan



[sqlite] CTE for a noob

2016-03-09 Thread David Raymond
For my own clarification, the statements quoted way down below aren't exactly 
equivalent, correct?

"For each pair of columns identified by a USING clause, the column from the 
right-hand dataset is omitted from the joined dataset. This is the only 
difference between a USING clause and its equivalent ON constraint."

(Short version: USING will return fewer fields than ON, and order can matter 
for both types because of affinity/collation)

So if you have tables tA and tB (ID integer, FirstName text COLLATE NOCASE, 
LastName text COLLATE NOCASE)...
with contents
tA: (1, 'john', 'smith')
tB: (2, 'JOHN', 'SMIth')

then
select * from tA inner join tB USING (FirstName, LastName);
gives
1, 'john', 'smith', 2

select * from tB inner join tA USING (FirstName, LastName);
gives
2, 'JOHN', 'SMIth', 1

and
select * from tA inner join tB on tA.Firstname = tB.FirstName and tA.LastName = 
tB.LastName;
gives
1, 'john', 'smith', 2, 'JOHN', 'SMIth'


And let's say tB did NOT have the COLLATE NOCASE, then
select * from tA inner join tB USING (FirstName, LastName);
would use tA's NOCASE collation (first table listed) for all fields and return 
the 1 record,

whereas
select * from tA inner join tB ON tB.FirstName = tA.FirstName and tB.LastName = 
tA.LastName;
would use tB's BINARY collation (tB on the left side of the =) and return no 
records.


-Original Message-
From: sqlite-users-bounces at mailinglists.sqlite.org 
[mailto:sqlite-users-boun...@mailinglists.sqlite.org] On Behalf Of R Smith
Sent: Tuesday, March 08, 2016 12:11 PM
To: sqlite-users at mailinglists.sqlite.org
Subject: Re: [sqlite] CTE for a noob



On 2016/03/08 5:02 AM, Stephen Chrzanowski wrote:
> Now I'll have to use USING a bit more often to get the drift and get 
> out of this multi-call thing.  I sort of see what is going on here, 
> but practice is whats needed.

"USING" has three uses in SQLite, first to enlist a virtual table, secondly to 
suggest an Index to the Query Planner and thirdly as in the example Igor gave 
where "USING" is simply short-hand for a join where the joining index fields 
are simple and named the same. This is defined in the standard as a join 
operation, by the way, works everywhere so not special to SQLite.

Easiest is probably by dual example - these two statements are equivalent:
SELECT *
   FROM tA
   JOIN tB USING (ID)

vs.

SELECT *
   FROM tA
   JOIN tB ON tB.ID = tA.ID

Of course this next query can't be simplified since the field-names do not 
match:

SELECT *
   FROM tA
   JOIN tB ON tB.ParentID = tA.ID

which might make the "USING" thing seem a bit overrated at first glance, but 
consider the following equivalent queries to see its simplifying power:

SELECT *
   FROM tA
   JOIN tB ON tB.Surname = tA.Surname AND tB.FirstName = tA.FirstName AND 
tB.DateOfBirth = tA.DateOfBirth

vs.

SELECT *
   FROM tA
   JOIN tB USING (Surname, FirstName, DateOfbirth)

the basic format of which, I might add, covers a very large percentage of 
typical joined queries.


Cheers!
Ryan

___
sqlite-users mailing list
sqlite-users at mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] CTE for a noob

2016-03-08 Thread R Smith


On 2016/03/08 5:02 AM, Stephen Chrzanowski wrote:
> Now I'll have to use USING a bit more often to get the drift and get out of
> this multi-call thing.  I sort of see what is going on here, but practice
> is whats needed.

"USING" has three uses in SQLite, first to enlist a virtual table, 
secondly to suggest an Index to the Query Planner and thirdly as in the 
example Igor gave where "USING" is simply short-hand for a join where 
the joining index fields are simple and named the same. This is defined 
in the standard as a join operation, by the way, works everywhere so not 
special to SQLite.

Easiest is probably by dual example - these two statements are equivalent:
SELECT *
   FROM tA
   JOIN tB USING (ID)

vs.

SELECT *
   FROM tA
   JOIN tB ON tB.ID = tA.ID

Of course this next query can't be simplified since the field-names do 
not match:

SELECT *
   FROM tA
   JOIN tB ON tB.ParentID = tA.ID

which might make the "USING" thing seem a bit overrated at first glance, 
but consider the following equivalent queries to see its simplifying power:

SELECT *
   FROM tA
   JOIN tB ON tB.Surname = tA.Surname AND tB.FirstName = tA.FirstName 
AND tB.DateOfBirth = tA.DateOfBirth

vs.

SELECT *
   FROM tA
   JOIN tB USING (Surname, FirstName, DateOfbirth)

the basic format of which, I might add, covers a very large percentage 
of typical joined queries.


Cheers!
Ryan



[sqlite] CTE for a noob

2016-03-08 Thread Drago, William @ CSG - NARDA-MITEQ
Have you seen this tutorial?

https://blog.expensify.com/2015/09/25/the-simplest-sqlite-common-table-expression-tutorial/

--
Bill Drago
Staff Engineer
L3 Narda-MITEQ
435 Moreland Road
Hauppauge, NY 11788
631-272-5947 / William.Drago at L-3COM.com


> -Original Message-
> From: sqlite-users-bounces at mailinglists.sqlite.org [mailto:sqlite-users-
> bounces at mailinglists.sqlite.org] On Behalf Of Stephen Chrzanowski
> Sent: Monday, March 07, 2016 9:47 PM
> To: General Discussion of SQLite Database
> Subject: [sqlite] CTE for a noob
>
> I'd like to learn how to use CTEs by example when working on my own
> project, by mutating it from individual calls into one clean call.  I looked 
> at the
> page (As I said in my previous email/note/post(?)) and just thought I'd put
> this question out there.
>
> Given I have the schema posted here: http://pastebin.com/hA6weV4n
>
> Currently my application makes two queries to the database.  One to get the
> list of projects via [ select ProjectID,Description from Projects order by
> Description ]
>
> It then goes through each record retrieved and then gets another query via [
> select (select count(VideoID) from vViewedVideos where DateViewed is null
> and ProjectID=:P) Unwatched, (select count(VideoID) from vViewedVideos
> where ProjectID=:P) Videos ] where :P is the ProjectID.
>
> I then take the results of ProjectID, Description, Unwatched and Watched
> and format a string to put it into a listbox on the form.
>
> I want to change the order in which this listbox is populated based on a 
> single
> query and the final sort order of [ order by Unwatched=0, Unwatched ] so
> that anything that has no unwatched videos available are at the bottom of
> list, and any videos that have something to watch are sorted ascending at the
> top of the list, 1 to whatever  Maybe even add the flexibility later on down
> the line so that I can change the order based on [ order by Description ] or [
> Unwatched=0, Description ] or whatever, just by changing the final Order By
> clause at runtime.
>
> From what magic I've seen on the CTE page at sqlite.org, this should be easy
> to do, but I've not a clue where to start.
>
> If you'd like to look at the raw database, it is found here:
> https://dl.dropboxusercontent.com/u/1598459/sql/videos.db3
>
> Any hints and thoughts would be appreciated!
> ___
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
CONFIDENTIALITY, EXPORT CONTROL AND DISCLAIMER NOTE:This e-mail and any 
attachments are solely for the use of the addressee and may contain information 
that is privileged or confidential. Any disclosure, use or distribution of the 
information contained herein is prohibited. In the event this e-mail contains 
technical data within the definition of the International Traffic in Arms 
Regulations or Export Administration Regulations, it is subject to the export 
control laws of the U.S.Government. The recipient should check this e-mail and 
any attachments for the presence of viruses as L-3 does not accept any 
liability associated with the transmission of this e-mail. If you have received 
this communication in error, please notify the sender by reply e-mail and 
immediately delete this message and any attachments.


[sqlite] CTE for a noob

2016-03-07 Thread Stephen Chrzanowski
Awesome... And no CTE.  General over complications and over thinking and
tunnel-visioned on my part.  I just had to tag on whatever sort order I
want, and voila.  Appreciated.

Now I'll have to use USING a bit more often to get the drift and get out of
this multi-call thing.  I sort of see what is going on here, but practice
is whats needed.

Thanks again!

On Mon, Mar 7, 2016 at 9:56 PM, Igor Tandetnik  wrote:

> On 3/7/2016 9:47 PM, Stephen Chrzanowski wrote:
>
>> Currently my application makes two queries to the database.  One to get
>> the
>> list of projects via [ select ProjectID,Description from Projects order by
>> Description ]
>>
>> It then goes through each record retrieved and then gets another query via
>> [ select (select count(VideoID) from vViewedVideos where DateViewed is
>> null
>> and ProjectID=:P) Unwatched, (select count(VideoID) from vViewedVideos
>> where ProjectID=:P) Videos ] where :P is the ProjectID.
>>
>
>
> select ProjectID, Description,
>   sum(VideoID is not null and DateViewed is null) Unwatched,
>   count(VideoID) Videos
> from Projects left join vViewedVideos using (ProjectID)
> group by ProjectID;
>
> --
> Igor Tandetnik
>
> ___
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>


[sqlite] CTE for a noob

2016-03-07 Thread Igor Tandetnik
On 3/7/2016 9:47 PM, Stephen Chrzanowski wrote:
> Currently my application makes two queries to the database.  One to get the
> list of projects via [ select ProjectID,Description from Projects order by
> Description ]
>
> It then goes through each record retrieved and then gets another query via
> [ select (select count(VideoID) from vViewedVideos where DateViewed is null
> and ProjectID=:P) Unwatched, (select count(VideoID) from vViewedVideos
> where ProjectID=:P) Videos ] where :P is the ProjectID.


select ProjectID, Description,
   sum(VideoID is not null and DateViewed is null) Unwatched,
   count(VideoID) Videos
from Projects left join vViewedVideos using (ProjectID)
group by ProjectID;

-- 
Igor Tandetnik



[sqlite] CTE for a noob

2016-03-07 Thread Stephen Chrzanowski
I'd like to learn how to use CTEs by example when working on my own
project, by mutating it from individual calls into one clean call.  I
looked at the page (As I said in my previous email/note/post(?)) and just
thought I'd put this question out there.

Given I have the schema posted here: http://pastebin.com/hA6weV4n

Currently my application makes two queries to the database.  One to get the
list of projects via [ select ProjectID,Description from Projects order by
Description ]

It then goes through each record retrieved and then gets another query via
[ select (select count(VideoID) from vViewedVideos where DateViewed is null
and ProjectID=:P) Unwatched, (select count(VideoID) from vViewedVideos
where ProjectID=:P) Videos ] where :P is the ProjectID.

I then take the results of ProjectID, Description, Unwatched and Watched
and format a string to put it into a listbox on the form.

I want to change the order in which this listbox is populated based on a
single query and the final sort order of [ order by Unwatched=0, Unwatched
] so that anything that has no unwatched videos available are at the bottom
of list, and any videos that have something to watch are sorted ascending
at the top of the list, 1 to whatever  Maybe even add the flexibility later
on down the line so that I can change the order based on [ order by
Description ] or [ Unwatched=0, Description ] or whatever, just by changing
the final Order By clause at runtime.

>From what magic I've seen on the CTE page at sqlite.org, this should be
easy to do, but I've not a clue where to start.

If you'd like to look at the raw database, it is found here:
https://dl.dropboxusercontent.com/u/1598459/sql/videos.db3

Any hints and thoughts would be appreciated!