MYSQL (WHERE - IF - SELECT/IN statement) - mysql

I'm trying to set my code up where I have a Control Panel for my Sales Reps.
From my Control Panel, I am able to control which customers a Rep calls based on the item the customer bought.
i.e. If I assign "Cars" in my Control Panel for Sales Rep 01, he would only call customers that bought toys in the "Cars" category. And all different toys in my "Cars" category are stored in a separate file named "Vehicles".
My files are as follows:
customer (File)
+--------+-----------+--------+
| name | phone | toy |
+--------+-----------+--------+
| Gail | 777-1234 | Truck |
| June | 777-1235 | Doll |
| Mary | 777-1236 | Racer |
| Bill | 777-1237 | Ball |
| Jon | 777-1238 | Jeep |
+--------+-----------+--------+
control_panel (File)
+----------+--------+
| user | desc |
+----------+--------+
| sales_01 | Cars |
+----------+--------|
vehicles (File)
+---------+
+ item |
+---------+
| Truck |
| Racer |
| Jeep |
+---------+
In trying to test this code out, I have this portion of my code working.
select
c.name , c.phone
FROM
customer c
WHERE
c.toy IN (
SELECT
v.item
FROM
vehicles v
)
Now I'm trying to condition my WHERE statement so that only if I choose "Cars" in my Control Panel screen for User "sales_01", then customers who bought Cars will only show on the Call Screen for User "sales_01".
This is one example of some of the code I've been testing but cant get to work correctly.
SELECT
c.name , c.phone
FROM
customer c , control_panel p
WHERE
(IF p.desc = "Cars"
THEN (c.toy
IN (SELECT
v.item
FROM
vehicles v)
)
END)
Any help is appreciated. Thx.

To start with, I suggest you refactor your schema by adding an field category to your vehicles table. This will allow a proper relationship between your control_panel and customer. In that case you could just do SELECT c.name, c.phone FROM customer c LEFT OUTER JOIN vehicles v ON c.toy = v.items WHERE v.category = 'Cars'. I would have loved to add other suggestions but I feel you want something that could work right now. Plus, I do not have much time to spare presently. Hope this helps.

Related

Join query on Wordpress usermeta

We all love wordpress right?
So I've had to work with the usermeta table that basically have this structure.
umeta_id | user_id | meta_key | meta_value
For some reasons several in-house developer plugins wrote a lot of additional information on this table and lately I won the duty to work with it and pull out some important information that I need to export and save in a structure that actually make sense for a web application.
To provide an example this is the kind of data that I can find:
umeta_id | user_id | meta_key | meta_value
1 | 1 | ourID | asdad878d7a
2 | 1 | country | fooland
3 | 1 | firstname| foo
4 | 1 | lastname | bar
I would like to create a result that resemble this structure:
user_id | ourID | country
1 | asdad878d7a | fooland
I tried something but really this kind of structure isn't something I'm accustomed too.
This is my query so far:
SELECT meta.umeta_id as umeta_id, meta.user_id as user_id, channel.meta_value as ourID, country.meta_value as country
FROM usermeta as meta
INNER JOIN usermeta as channel
INNER JOIN usermeta as country
WHERE channel.meta_key = 'ourID'
AND country.meta_key = 'country'
But the result is basically something wrong. I'm having lots of duplicate of the same user_id, one for every row assigned to the user_id but only reporting the field selected instead of the value. Now while this make sense I don't know how to correctly write this query.
Something like this:
umeta_id | user_id | ourID | country
1 | 51424 | UC6Y94UM6rj | United Kingdom
1 | 51424 | UC6Y94UM6rj | Italy
1 | 51424 | UC6Y94UM6rj | Italy
1 | 51424 | UC6Y94UM6rj | Italy
1 | 51424 | UC6Y94UM6rj | Croatia
1 | 51424 | UC6Y94UM6rj | United States
1 | 51424 | UC6Y94UM6rj | Croatia
Clearly I'm doing something very wrong and I'm here hoping that someone can help me understand how to run this kind of query properly more than having the query done by someone else.
Would this get you closer to what you are looking for?
SELECT meta.umeta_id as umeta_id, meta.user_id as user_id, meta.meta_value as ourID, country.meta_value as country
FROM usermeta as meta
INNER JOIN usermeta as country ON meta.user_id = country.user_id
WHERE meta.meta_key = 'ourID'
AND country.meta_key = 'country'
The logic is to first find an entry that has meta_key 'ourID'. The value of user_id and ourID are picked up from this entry, so the inner join is only required to merge the value of country. The ON condition in INNER JOIN selects the correct country entry.

How to formulate query to show all courses taken by a person

I'm having trouble formulating a MySQL query correctly. Everything I've tried doesn't give me what's needed, or gives a syntax error.
I have three tables: Clients, Courses, and CoursesForClients.
The Clients table just has basic coordinates for a person: ID, Name, Address, email, etc.
+----------+-----------------------------+------+
| ClientID | Name | Address | etc. |
+----------+-----------------------------+------+
| 10 | Joe Smith | 1 Main St. | ... |
| 20 | Bob Smith | 2 Main St. | ... |
| ... | ... ... | ... ... ... | ... |
+----------+-----------------------------+------+
The Courses table stores the course name and its ID.
+----------+-----------------------+
| CourseID | Name |
+----------+-----------------------+
| 100 | Intro. to Subject |
| 200 | Intermediate Subject |
| 300 | Advanced Subject |
| ... | ... ... ... ... |
+----------+-----------------------+
The CoursesForClients table has the CourseID and ClientID. A given Client can have taken multiple courses, so for every course that a Client has taken, there's a row, with the person's ID and the Course ID.
+----------+----------+
| CourseID | ClientID |
+----------+----------+
| 100 | 1 |
| 200 | 1 |
| 300 | 1 |
| 100 | 2 |
| 200 | 2 |
| ... | ... |
+----------+----------+
Now, what I need is to be able to list the Client - just once - together with all the Courses she has taken. So, the result of the query might look like this:
10:Joe Smith
1 Main St.
Somewhere, AL
Intro. to Subject
Intermediate Subject
Advanced Subject
---------------------------
20:Bob Smith
2 Main St.
Somewhere, AL
Intro. to Subject
Intermediate Subject
So this output reflects the relationships between the Client and the Course. The key thing here is that, no matter how many Courses a Client has taken, the Client's particulars appear only once, followed by the list of all the courses she's taken.
There's an additional twist in that there's another table that lists the Grade for the Course for the Client, and that GradeID is also stored in the CoursesForClients table, and there's another table of Grades, with ID and Grade Description. But I won't worry about this right now. For now, all I want is just the basic output shown, as described above.
It looks like it should be easy to set up a query for this, with a JOIN and maybe a GROUP BY, but I'm having a block here and can't seem to get it right. So, any help will be hugely appreciated. Thank you!
SQL deals in tables. By definition a table has a bunch of rows, each of which has the same columns as each other. Your query is going to yield a result set that duplicates the client's information for each course she took.
Your presentation layer is going to format that table, by noticing the first row of each new client and breaking out the client header. You'll do that in php or Java or Crystal Reports or some such presentation tech.
Your query is something like this.
SELECT a.id, a.name, a.address, a.etc,
c.Name
FROM Clients a
JOIN CoursesForClients b USING(ClientID)
JOIN Courses c USING(CourseID)
ORDER BY a.id, c.CourseID
#Strawberry makes a good point about the pitfall of using USING(). Here is the same query on ON.
SELECT a.id, a.name, a.address, a.etc,
c.Name
FROM Clients a
JOIN CoursesForClients b ON a.ClientID = b.ClientID
JOIN Courses c ON b.CourseID = c.CourseID
ORDER BY a.id, c.CourseID

MySQL - join on same table?

I'm trying to implement this answer, which shows how, using table aliases, you can effectively join to the same table you're running the query on.
Consider the following (simplified) table of football teams:
-----------------------------------------------------
| id | name | next_fixture_against | url_token |
=====================================================
| 1 | Hull City | 2 | hull |
-----------------------------------------------------
| 2 | Everton | 1 | everton |
-----------------------------------------------------
I'm trying to write a query that fetches the names of a given team and its next opponent.
Approach 1: left join
Here's what I came up with by adapting the above answer:
SELECT main_team.name, opposition_team.name as against
FROM teams AS main_team
LEFT JOIN teams AS opposition_team
ON main_team.name = opposition_team.next_fixture_against
WHERE main_team.url_token = 'hull'
That produces:
-----------------------
| name | against |
=======================
| Hull City | NULL |
-----------------------
If I remove the WHERE clause, it does work, but, strangely, it comes out in the reverse order from that which I'd expect, i.e.
-----------------------
| name | against |
=======================
| Everton | Hull City |
-----------------------
rather than name = Hull City, against = Everton.
(This is purely a point of interest - clearly I need the where clause as I'm targeting a particular team, not all teams.)
Approach 2: sub-query
I came up with the following, alternate approach:
SELECT
name,
(SELECT name FROM teams WHERE id = ???) AS against
FROM
teams
WHERE
url_token = 'hull'
...but I'm not sure what to replace ??? with to get the inner sub-query to reference the outer one.
Can anyone point me in the right direction? Thanks in advance.
You need ON main_team.id = opposition_team.next_fixture_against. You tried to use the team name rather than id in the join.
Don't worry, we've all done this.

Order column by certain criteria in mysql

I need to be able to order my output data in a proper way using MySQL.
I'm using ORDER BY so far and everything was working correctly until now.
Let's say I have something like this:
Table VEHICLES:
ID | Name | MainGroup | SubGroup
1 | A | Vehicle | Truck
2 | B | Vehicle | Car
3 | C | Vehicle | Car
4 | D | Vehicle | Truck
5 | E | Vehicle | Truck
6 | F | Vehicle | Motorbike
I was using this:
SELECT * FROM Vehicles WHERE MainGroup=Vehicle ORDER BY Subgroup;
When I get selections they are not sorted in a way that I want, because now I want to be able to determine the way of the selected ones. Let's say that I want an output like this Car, Truck, Motorbike or some other way around. How to achieve this?
Is this doable using an order by?
Use field():
SELECT *
FROM Vehicles
WHERE MainGroup=Vehicle
ORDER BY field(Subgroup, 'Car', 'Truck', 'Motorbike');

How to write a proper If...Else Statement with JOIN in MySQL?

I'm quite a beginner in MySQL I just know the totally basic statements, however now I'ts time for me to get into some more difficult, but worth stuff.
I actually have 3 tables in MySQL, here is the representation:
users:
user_id | name | country
---------------------------
1 | Joseph | US
2 | Kennedy | US
3 | Dale | UK
admins:
admin_id | name | country
----------------------------
1 | David | UK
2 | Ryan | US
3 | Paul | UK
notes:
id | n_id | note | comment | country | type | manager
----------------------------------------------------------------
1 | 3 | This is the 1st note | First | US | admin | 2
2 | 2 | This is the 2nd note | Second | US | user | 1
3 | 2 | This is the 3rd note | Third | UK | user | 2
Now I would like to execute something like this SQL (I'm going to type not real commands here, because I'm not really familiar with all of the SQL expressions):
IF notes.type = admin
THEN
SELECT
notes.note,
notes.comment,
notes.country,
admins.name,
admins.country
FROM notes, admins
WHERE notes.n_id = admin.admin_id
ELSEIF notes.type = 'user'
SELECT
notes.note,
notes.comment,
notes.country,
users.name,
users.country
FROM notes, users
WHERE notes.n_id = users.user_id
I hope you understand what would I like to achieve here. I could do this easily with more SQL statements, but I would like to try some query which doesn't use that much resources.
Edit 1:
I would like to Get all of the Notes and get which usergroup has submitted it than apply the user's name to it. I mean, if the admin submitted the note, than SQL should choose the ID from the Admin table (as per the type value) but if a User submitted the note, it should get the name from the Users table.
The result should look something similar to this:
result:
------
id | note | comment | country | name
--------------------------------------------------------
1 | This is the 1st note | First | US | Paul
2 | This is the 2nd note | Second | US | Kennedy
3 | This is the 3rd note | Third | UK | Kennedy
Edit 2:
I have actually forgot to mention, that all of these should be listed to a manager. So a 'manager ID' should be added to the Notes and list all of the notes where the manager is for example: 2.
Here is a method that you can do in one query:
SELECT n.note, n.comment, n.country,
coalesce(a.name, u.name) as name, coalesce(a.country, u.country) as country
FROM notes n left join
admins a
on n.n_id = a.admin_id and n.type = 'admin' left join
users u
on n.n_id = u.user_id and n.type = 'user';
This uses left join to bring the records together from both tables. It then chooses the matching record for the select.
To select a particular manager, remove the semicolon and add:
where n.manager = 2;
If you expect admins and users in one result you have got several options. The simplest way is to make a union select like this:
SELECT
notes.note,
notes.comment,
notes.country,
admins.name,
admins.country
FROM
notes join admins on notes.n_id = admin.admin_id
WHERE
notes.manager = 2
UNION ALL
SELECT
notes.note,
notes.comment,
notes.country,
users.name,
users.country
FROM
notes join users on notes.n_id = users.user_id
WHERE
notes.manager = 2