The JOIN syntax in SQL that no-one knows about

Поделиться
HTML-код
  • Опубликовано: 7 июл 2024
  • There is a type of JOIN that has existed in the Oracle Database for over 20 years, yet almost no-one has heard of it, even fewer use it regularly but it makes a whole class of complex SQL problems trivial to solve
    Follow me!
    blog: connor-mcdonald.com
    twitter: / connor_mc_d
    The Podcast!
    podcasts.apple.com/au/podcast...
    open.spotify.com/show/5dqVVft...
    Subscribe for new tech videos every week
    Other social media channels here: linktr.ee/connor
    Music: Night Owl (Broke For Free), Kevin Mcleod (incomptech), Dyalla
    #sql #database
  • НаукаНаука

Комментарии • 72

  • @cakeman58
    @cakeman58 25 дней назад +17

    Hi Conner. I'm retired for over 2 years now and don't play in Oracle like I used to (daily). I felt my SQL skills were pretty strong after using Oracle for almost 30 years, but I have to admit I didn't know about a partitioned outer join. Thanks for posting about this!

    • @DatabaseDude
      @DatabaseDude  24 дня назад +3

      That is why it was worth a video!

  • @hoi-polloi1863
    @hoi-polloi1863 12 дней назад +2

    This is really nice! I suppose you could get a similar result by joining the scores against a full join on the list of unique quarters vs unique players, but this partitioned business seems really clean.

    • @DatabaseDude
      @DatabaseDude  10 дней назад +2

      Yes, you can achieve it with a full join, but not sure how well that would scale to a real world case (eg 100s of thousands of customers across, say, 12 months)

  • @monawoka97
    @monawoka97 19 дней назад +2

    Man as a C++ dev SQL is like a whole other world. It makes sense but I have to stare at the syntax for so long to understand what it's doing.

  • @krakajak67
    @krakajak67 25 дней назад +3

    I learn something about SQL every time I watch your videos. And that’s after nearly 40 years working with SQL databases. Thanks.

  • @orterves
    @orterves 20 дней назад +4

    I would have probably done that dual cross joined to a query of players, then left joined to the player quarter

    • @DatabaseDude
      @DatabaseDude  19 дней назад

      Indeed - there are plenty of solutions, but I always like solutions that are simple and easy.

  • @ehsnils
    @ehsnils 20 дней назад +1

    I started with SQL in the beginning of the 1990's on Oracle (5.1) and at that time there wasn't even a "LEFT" or "RIGHT" join, at most you could use a (+) syntax to make some things happening - and for some tricks it was necessary to create temporary tables to be efficient.

    • @DatabaseDude
      @DatabaseDude  13 дней назад

      ANSI joins came in for oracle at around 9i timeframe

  • @LewisCowles
    @LewisCowles 25 дней назад +6

    Why did you use this very Oracle specific syntax?
    It's interesting, but I'm not sure folks shouldn't jam in a few CTE's (1-4 is a very short union) and then cross-join distinct players, with the quarters. Even using NVL vs COALESCE seems to be a quite specific oracle-ism.
    Nice video, just looked like you were doing this on a phone, to which I'd considered that it would be sqlite.

    • @DatabaseDude
      @DatabaseDude  24 дня назад +3

      "very Oracle specific syntax" ...... Um... partitioned outer is in the SQL Standard (F403). Just because other vendors haven't caught up doesn't mean its "specific"

    • @professortrog7742
      @professortrog7742 20 дней назад +3

      @@DatabaseDude
      F403 is intentionally omitted in the PostgreSQL implementation.
      And Dual is an oracle-ism too.

    • @jcwynn4075
      @jcwynn4075 20 дней назад +3

      ​@@DatabaseDude that's literally the definition of specific 😂 also, word of advice: didn't be sassy in your own comment section

  • @LuminousWatcher
    @LuminousWatcher 20 дней назад +6

    I guess that the title should have been "The JOIN syntax in Oracle SQL that no-one knows about" - I do not see this in MySQL, DB2 or MariaDB, which i usually work with - an interesting function nontheless

    • @DatabaseDude
      @DatabaseDude  19 дней назад +6

      It's not up to Oracle what other vendors decide to leave out of their implementation. Partitioned outer join is in the SQL standard

  • @RonPowell-i9g
    @RonPowell-i9g 20 дней назад +3

    I'm not a database guy at all. I've done a bit of SQL work a long time ago. Real reason I'm here? The greyhound thumbnail picture :)

    • @orterves
      @orterves 20 дней назад

      I work with SQL and databases daily
      I'm still only here because of the greyhound

    • @DatabaseDude
      @DatabaseDude  19 дней назад

      Real reason I make tech videos? To post pictures of my hound :-)

    • @DatabaseDude
      @DatabaseDude  19 дней назад +1

      Bailey (my hound) likes your comment

    • @RonPowell-i9g
      @RonPowell-i9g 19 дней назад

      @@DatabaseDude I fully endorse this course of action, sir!

  • @vikram4755
    @vikram4755 11 дней назад

    Wow.. thankfully after this i am not the one who doesnt know this 😂
    Thanks Connor.

  • @geoffstrickler
    @geoffstrickler 17 дней назад

    Useful, and I think that’s unique to Oracle. The Syntax in SQL Server or other systems may be different.
    Now, for your specific example, what would be a useful addition is play time by quarter. Clearly that’s additional data entry and likely a separate table that tracks (at a minimum) times of player substitutions, from which you can create play-time by player by quarter, then join that to the score information. And, of course, you can also use that to show or omit players didn’t play in a game or range of games.

    • @DatabaseDude
      @DatabaseDude  10 дней назад +2

      Agreed - but whilst fine for a basketball game, not sure that would scale nicely to a real world enterprise use case (eg 10,000 customers across 12 months etc)

  • @StephenMoreira
    @StephenMoreira 16 дней назад

    Yea very neat, did that back in the day when I had a more SQL intensive role.

  • @optimizer77
    @optimizer77 20 дней назад

    Hi Conner, very interesting, thanks for sharing! Last time I worked with SQL was more than 10 yrs ago. I am curious, maybe it would even work by partitioning also by quarter? (basically getting rid of the synthesized table altogether and also the right outer join...)

    • @DatabaseDude
      @DatabaseDude  13 дней назад +1

      we need something to join to in order to use the "partition by"

  • @Meower68
    @Meower68 18 дней назад

    I've used partition by on something like row_number() but never seen it on a join. Good one!
    I was going to query out a unique list of players, do a cross join on quarters (probably as a TVC), giving me a full set of tuples, then join that against the actual points data. I've done something similar, in the past, on DB/2. This is simpler. Will need to see just how many other databases out there implement that.

    • @DatabaseDude
      @DatabaseDude  13 дней назад

      a cartesian product is definitely an option in this (small data) case, but if you extrapolate that to a more real world example, that could get expensive very fast

  • @SandeepSandhu
    @SandeepSandhu 25 дней назад +1

    Awesome!!

  • @mohamedaminesekkai7326
    @mohamedaminesekkai7326 25 дней назад +1

    Does it work on 11g 11.2.0.3 ?

  • @debpatro
    @debpatro 25 дней назад

    🙏, I learned a new thing today.

  • @theboss9885
    @theboss9885 25 дней назад +1

    Really no one knows it..thanks Conner

  • @brianfisher6799
    @brianfisher6799 19 дней назад

    In SQL Server i just cross join into a temp table constrained by whatever interval is needed and then select from that temp and left join to the data. Could also use CTE if you have a date dimension...

    • @DatabaseDude
      @DatabaseDude  13 дней назад

      true, but I think that is going to be a much more complicated SQL

  • @m9600174
    @m9600174 19 дней назад

    Can you use this trick for both the quarter and player at once (so you don't have to generate the fake table with the 4 quarters)?

    • @DatabaseDude
      @DatabaseDude  13 дней назад

      You need to join to *something*

  • @johnkelly9970
    @johnkelly9970 20 дней назад

    This is good. Well explained

    • @DatabaseDude
      @DatabaseDude  19 дней назад

      Thank you!

    • @johnkelly9970
      @johnkelly9970 15 дней назад

      @@DatabaseDude Wondering if there's a CROSS APPLY and OUTER APPLY video in the works ? : )

  • @iudithmentzel6288
    @iudithmentzel6288 25 дней назад +2

    I think you should start to teach APEX also.
    For me, it will be my only way to learn APEX ... :)

  • @andymoss4285
    @andymoss4285 19 дней назад

    I like this trick

  • @jasfigueroa
    @jasfigueroa 25 дней назад

    I had not seen that use of PARTITION BY before so I asked our AI SQL Overlord for an explanation.... It seems that there is no spoon ;)
    The query you provided is a bit unusual in that it includes a PARTITION BY clause without an OVER clause, which is typically how window functions are used. In SQL, PARTITION BY is usually used within the context of a window function to define the partitions on which the window function operates. However, the provided query seems to mix the syntax and semantics of different SQL dialects or perhaps contains a typo.
    Clarifying the Intended Query
    Let's break down and correct the query for better understanding.
    Original Oracle Query
    sql
    Copy code
    SELECT qtr, player, NVL(pts, 0)
    FROM (
    SELECT quarter, player, SUM(points) pts
    FROM basketball
    GROUP BY quarter, player
    ) b
    PARTITION BY (b.player) -- This seems incorrect or misplaced
    RIGHT OUTER JOIN (
    SELECT rownum qtr FROM dual CONNECT BY LEVEL

    • @DatabaseDude
      @DatabaseDude  24 дня назад

      No typo :-) That is right where the PARTITION command goes for a partitioned join

    • @orterves
      @orterves 20 дней назад +1

      The AI gets confused because this is a very obscure syntax that Oracle implements (and pretty much nothing else does, apparently).

  • @thomasbrotherton4556
    @thomasbrotherton4556 25 дней назад

    Why not do some type of pivot? You could list one row per player, with columns for each quarter going across.

    • @DatabaseDude
      @DatabaseDude  22 дня назад

      Sure, that would work, but why immediately jump to changing the requirement?

  • @lyrebird712
    @lyrebird712 19 дней назад

    Would love if I could use this at work. Neither of our databases support this so I have a whole list of utility tables that I join with to get similar functionality.

    • @DatabaseDude
      @DatabaseDude  13 дней назад

      "neither"- what database ?

    • @lyrebird712
      @lyrebird712 13 дней назад

      @@DatabaseDude MySQL 5.1 and 8.-something (don't recall the exact version, most of our applications are on the old one). I did look the docs up the other day at work and didn't see it :(

  • @nothinghere1996
    @nothinghere1996 7 дней назад

    great language.

  • @peabody3000
    @peabody3000 19 дней назад

    why not a simple left outer join?

    • @DatabaseDude
      @DatabaseDude  19 дней назад

      Try it - you don't get the correct answer

  • @fisherh9111
    @fisherh9111 14 дней назад

    this is why I prefer Excel.

    • @DatabaseDude
      @DatabaseDude  13 дней назад

      fine for 100 rows...not so fine for 100million

    • @fisherh9111
      @fisherh9111 13 дней назад

      @@DatabaseDude who needs more than 100 rows? Only 12 months in the year!

  • @RoamingAdhocrat
    @RoamingAdhocrat 18 дней назад +1

    ah, you started out so personable, but as soon as you said `select from dual` your eyes went black and a swarm of snakes came out of your mouth

    • @DatabaseDude
      @DatabaseDude  13 дней назад +1

      you'll need to upgrade to 23ai then

  • @ItsMrVD
    @ItsMrVD 20 дней назад

    🤨

  • @janbrittenson210
    @janbrittenson210 18 дней назад

    Why not just have a second table with the players who played in each quarter and join with that. It would seem that if a player only played in one quarter you don't want 0's listed for the three they didn't play in...

    • @DatabaseDude
      @DatabaseDude  13 дней назад

      You could do that, but now you've got another table to maintain, populate, keep in sync with the base data.

  •  17 дней назад +2

    PARTITION BY is regular SQL. However, CONNECT BY is an Oracle-specific feature. It could have been stated early in the video. Nice video and good information but currently just wasted my time.

    • @DatabaseDude
      @DatabaseDude  13 дней назад +1

      true, but that element is not really the emphasis of the video - its just to synthesize some data. So you could take part and utilise whatever suits (generate_series etc etc)

  • @user-vo3st8kx7s
    @user-vo3st8kx7s 19 дней назад

    I'm not convinced, first I'm 100% percent sure right join are evil, second the partition thing smells too much Oracle to be angel.😊

    • @DatabaseDude
      @DatabaseDude  13 дней назад

      If joins are evil, then perhaps relational databases are not for you :-)

    • @user-vo3st8kx7s
      @user-vo3st8kx7s 10 дней назад

      @@DatabaseDude read again, "right join" otherwise i won't bother watching.