{"id":28,"date":"2021-11-09T20:59:13","date_gmt":"2021-11-09T20:59:13","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/jsouther\/?p=28"},"modified":"2021-11-09T20:59:13","modified_gmt":"2021-11-09T20:59:13","slug":"my-struggle-with-slq-queries","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/jsouther\/2021\/11\/09\/my-struggle-with-slq-queries\/","title":{"rendered":"My Struggle with SLQ Queries"},"content":{"rendered":"\n<p>This last week I have spent a significant amount of time dealing with mildly complex SQL queries for our game. At least they are complex by my standards (your mileage may vary). My first problem I needed to tackle is the structure of our database. In the grand scheme of things, the database is rather straightforward but a certain many-to-many relationship has definitely been causing havoc on my brain.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"784\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4740\/files\/2021\/11\/image-1-1024x784.png\" alt=\"\" class=\"wp-image-29\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4740\/files\/2021\/11\/image-1-1024x784.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4740\/files\/2021\/11\/image-1-300x230.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4740\/files\/2021\/11\/image-1-768x588.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4740\/files\/2021\/11\/image-1.png 1244w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Our current database. Not too shabby.<\/figcaption><\/figure>\n\n\n\n<p>With the structure out of the way, I moved on to problem number two. The problem being, how do we retrieve all of the card entries from the cards table that belong to a specific user AND deck so that we can feed that into our script that handles creating decks to play the game. My first stab at it worked after a few tries however it makes you want to puke at first sight.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT\r\n  cards.cardID,\r\n  cards.cardName,\r\n  cards.description,\r\n  cards.portrait,\r\n  cards.summon,\r\n  cards.elementString,\r\n  cards.cost,\r\n  cards.life,\r\n  cards.attack,\r\n  cards.defense,\r\n  cards.cardMax,\r\n  cards.spellValue,\r\n  cards.spellType,\r\n  cardInDeck.cardCount\r\nFROM cards\r\nJOIN users ON\r\n  users.userID = cards.userID\r\nJOIN decks ON\r\n  users.userID = decks.userID\r\nJOIN cardInDeck ON\r\n  decks.deckID = cardInDeck.deckID\r\nWHERE\r\n  users.userID = '$userID' AND\r\n  decks.deckID = '$deckID' AND\r\n  cardInDeck.cardID = cards.cardID;<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\">Yuck!<\/p>\n\n\n\n<p>Turns out I really only need information from two tables and following the foreign key lines from table to table to accomplish my joins was a terrible idea. One single join should solve this issue.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT\r\n  cards.cardID,\r\n  cards.cardName,\r\n  cards.description,\r\n  cards.portrait,\r\n  cards.summon,\r\n  cards.elementString,\r\n  cards.cost,\r\n  cards.life,\r\n  cards.attack,\r\n  cards.defense,\r\n  cards.cardMax,\r\n  cards.spellValue,\r\n  cards.spellType,\r\n  cardInDeck.cardCount\r\nFROM cards\r\nJOIN cardInDeck \n  USING (cardID)\r\nWHERE\n  userID = '$userID' AND\n  deckID = '$deckID'<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center\">Much better. Only one JOIN needed!<\/p>\n\n\n\n<p>But wait, this code is still pretty smelly. That is one long list of columns to select from the cards table. In fact, it is every column in the cards table!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT\n  cards.*,\n  cardInDeck.cardCount\nFROM cards\nJOIN cardInDeck\n  USING (cardID)\nWHERE\n  userID = '$userID' AND\n  deckID = '$deckID'<\/code><\/pre>\n\n\n\n<p>Now we are finally getting somewhere. This query retrieves all the cards that are in the deck along with their associated info and the count of how many should be in the deck from the cardInDeck table. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Next Trouble<\/h2>\n\n\n\n<p>Following that, I needed to create a query that would do something very similar but indeed quite different. In order to edit a deck that a user has created we need to retrieve every card they have ever made as well as the number of individual cards they have included in the deck so far. So in this case we need ALL the user&#8217;s cards and the number of each assigned to the deck. Let us bring in the magic of LEFT JOIN and separating conditionals. For my first few attempts I could not figure out a way to do different conditionals on my selected table and the JOIN. However, it is possible! We simply must use conditionals <em>in<\/em> the JOIN statement and then another conditional on the WHERE statement that refers to SELECT.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT\r\n  cards.*,\r\n  cardInDeck.cardCount\r\nFROM cards\r\nLEFT JOIN cardInDeck\r\n  ON cards.cardID = cardInDeck.cardID AND\n  deckID = '$deckID'\r\nWHERE\n  userID = '$userID'<\/code><\/pre>\n\n\n\n<p>So in this case, I select everything from cards where userID matches the desired userID. Then, perform the join for matching cardID&#8217;s AND the desired deckID. So userID applies to the SELECT and deckID applies only to the JOIN. Obviously this is some fairly rudimentary SQL work but figuring it out was quite satisfying. Here&#8217;s to the next inevitable SQL query that must be resolved for our game. Cheers!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This last week I have spent a significant amount of time dealing with mildly complex SQL queries for our game. At least they are complex by my standards (your mileage may vary). My first problem I needed to tackle is the structure of our database. In the grand scheme of things, the database is rather&hellip; <a class=\"more-link\" href=\"https:\/\/blogs.oregonstate.edu\/jsouther\/2021\/11\/09\/my-struggle-with-slq-queries\/\">Continue reading <span class=\"screen-reader-text\">My Struggle with SLQ Queries<\/span><\/a><\/p>\n","protected":false},"author":11616,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-28","post","type-post","status-publish","format-standard","hentry","category-uncategorized","entry"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/posts\/28","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/users\/11616"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/comments?post=28"}],"version-history":[{"count":1,"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/posts\/28\/revisions"}],"predecessor-version":[{"id":30,"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/posts\/28\/revisions\/30"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/media?parent=28"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/categories?post=28"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/jsouther\/wp-json\/wp\/v2\/tags?post=28"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}