MySQL select join order by - mysql

I have two tables:
tb_user with these fields:
userId, lastName, firstName and other fields.
tb_application with these fields:
ApplicationID, ApplicantID, applicationType, applicationStatus, applicationCycle and other fields.
Using this statement I get the recordset of the applications ordered by ApplicationID.
SELECT tb_application.ApplicationID, tb_application.ApplicantID,
tb_application.applicationType, tb_application.applicationCycle,
tb_application.applicationStatus
WHERE applicationCycle = '10' and applicationType ='5' and and applicationStatus ='1'
ORDER BY tb_application.ApplicationID
Then, I use the field ApplicantID from the applications table to retrieve the name from the users table.
But what I need to have is the list of applications ordered by Last name.
After receiving the answer from Raphael and thanks to his diligence and introducing me to the power of the "JOIN" instruction in MySQL, I modify his answer and the one that works for me is this:
SELECT * FROM tb_application
INNER JOIN tb_user ON tb_application.ApplicantID=tb_user.userId
WHERE applicationCycle = '10'
and applicationType='5'
and applicationStatus='1'
ORDER BY lastName

SELECT
--u.lastName,
tb_t.ApplicationID,
t.ApplicantID,
t.applicationType,
t.applicationCycle,
t.applicationStatus
FROM tb_application t
INNER JOIN tb_user u
ON t.ApplicantID = u.userId
WHERE
applicationCycle = '10'
AND
applicationType ='5'
AND
applicationStatus ='1'
ORDER BY u.lastName

You can comma-sparate multiple fields to sort after, like this
ORDER BY tb_application.ApplicationID, tb_user.lastName
This means that it will first sort after tb_application.ApplicationID, and within that range it will sort after tb_user.lastName

Related

Cleaner SQL Query

I have 2 tables that are joined using foreign key, example: budget_items table column "id" and transactions tables column "parent_id"
Each table has some similar column names such as name and date for example. So when I query the table I'm pulling the data out as follows:
SELECT
budget_items.id AS BI_id,
budget_items.owner_id as BI_owner,
budget_items.name AS BI_name,
budget_items.date AS BI_date,
budget_items.amount AS BI_amount,
budget_items.type AS BI_type,
transactions.id as TRANS_id,
transactions.parent_id as TRANS_parent,
transactions.owner_id as TRANS_owner,
transactions.amount as TRANS_amount,
transactions.date as TRANS_date,
transactions.type as TRANS_type,
transactions.processed as TRANS_processed,
transactions.name AS TRANS_name
FROM
myezbudget.budget_items budget_items,
myezbudget.transactions transactions
WHERE
budget_items.id = transactions.parent_id AND
budget_items.owner_id = ?`, [req.user.id]
My question would be, is there a better way to do this with a more concise query? I tried with a few different types of join statements but couldn't get it to output the way I liked. I'm by no means a SQL expert and would appreciate any suggestions or guidance.
I would:
Use modern JOIN syntax.
Use shorter table aliases.
The query should look like:
SELECT
i.id AS BI_id,
i.owner_id as BI_owner,
i.name AS BI_name,
i.date AS BI_date,
i.amount AS BI_amount,
i.type AS BI_type,
t.id as TRANS_id,
t.parent_id as TRANS_parent,
t.owner_id as TRANS_owner,
t.amount as TRANS_amount,
t.date as TRANS_date,
t.type as TRANS_type,
t.processed as TRANS_processed,
t.name AS TRANS_name
FROM myezbudget.budget_items i
JOIN myezbudget.transactions t on i.id = t.parent_id
WHERE i.owner_id = ?
Yes you could use an inner join instead of selecting two tables in the FROM statement and linking them together in the WHERE by doing it like this:
SELECT
budget_items.id AS BI_id,
budget_items.owner_id as BI_owner,
budget_items.name AS BI_name,
budget_items.date AS BI_date,
budget_items.amount AS BI_amount,
budget_items.type AS BI_type,
transactions.id as TRANS_id,
transactions.parent_id as TRANS_parent,
transactions.owner_id as TRANS_owner,
transactions.amount as TRANS_amount,
transactions.date as TRANS_date,
transactions.type as TRANS_type,
transactions.processed as TRANS_processed,
transactions.name AS TRANS_name
FROM
myezbudget.budget_items budget_items,
INNER JOIN myezbudget.transactions AS transactions ON budget_items.id = transactions.parent_id
WHERE
budget_items.owner_id = ?`, [req.user.id]
You could always try shortening the table aliases as well to make them more compact but if you want them descriptive then that's fine. Also when the column only exists in one table then you don't have to specify the table name all of the time, however I would say this is personal preference.

Mysqli - #1052 - Column 'id' in field list is ambiguous

SELECT id,firstName,lastName, SUM(qty*price)
FROM orders,menu,customers
WHERE menu.id = orders.id_menu
AND orders.id_customer = customers.id
GROUP BY (id,firstName,lastName)
ORDER BY (SUM(qty*price)) LIMIT 1;
1052 - Column 'id' in field list is ambiguous
i need to get the best customer
Some simple rules when writing SQL:
Never use commas in the FROM clause.
Always use explicit, proper JOIN syntax.
Always alias your tables with abbreviations.
Always qualify your column references.
Your resulting queries are more likely to work the first time:
SELECT c.id, c.firstName, c.lastName, SUM(o.qty * m.price)
FROM orders o JOIN
menu m
ON m.id = o.id_menu JOIN
customers c
ON c.id = o.id_customer
GROUP BY c.id, c.firstName, c.lastName
ORDER BY SUM(o.qty * m.price)
LIMIT 1;
Change the query to this
SELECT customers.id,firstName,lastName, SUM(qty*price) FROM orders,menu,customers WHERE menu.id = orders.id_menu AND orders.id_customer = customers.id GROUP BY (customers.id,firstName,lastName) ORDER BY (SUM(qty*price)) LIMIT 1;
I believe all these tables have column called 'id' and you need to specify which one you need otherwise it will give you this message.
You have many columns as name 'id' in different tables so mysql can not know where is it from (menu.id vs customer.id).
change to:
SELECT id,firstName,lastName, SUM(qty*price)
FROM orders,menu,customers
WHERE menu.id = orders.id_menu
AND orders.id_customer = customers.id
GROUP BY (orders.id,firstName,lastName)
ORDER BY (SUM(qty*price)) LIMIT 1;
you want orders.id as those will be associated with qty and price

SQL Query - Determine who has only one gift record

I would like to know how I can write a SQL Script so a within a group of individuals initially selected:
SELECT [RECORDS].[CONSTITUENT_ID]
,[RECORDS].[FIRST_NAME]
,[RECORDS].[LAST_NAME]
,[DATEADDED]
,[DTE]
,[Amount]
,[REF]
,[TYPE]
FROM [re7].[dbo].[GIFT]
INNER JOIN [re7].[dbo].[RECORDS]
ON GIFT.CONSTIT_ID LIKE RECORDS.ID
WHERE ([DTE] BETWEEN '2/7/2015' AND '2/8/2015')
ORDER BY [DATEADDED] DESC
select only individuals who are "First Time Donors" (or someone who only has one gift in [re7].[dbo].[GIFT].
[RECORDS] is a table of all the constituents.
[GIFT] is a table of all recorded Gifts.
The output of the above Query, is just a table with:
CONSTITUENT_ID, FIRST_NAME, LAST_NAME, DATEADDED, DTE, Amount, REF, TYPE
I pretty much want to see the same output format, but I would like the query to select only CONSTITUENT_ID who only have 1 GIFT (by their Record ID) in [re7].[dbo].[GIFT].
I apologize for the lack of data to show. I wish I could describe better....
SELECT [RECORDS].[CONSTITUENT_ID]
,[RECORDS].[FIRST_NAME]
,[RECORDS].[LAST_NAME]
,[DATEADDED]
,[DTE]
,[Amount]
,[REF]
,[TYPE]
FROM [re7].[dbo].[GIFT]
INNER JOIN [re7].[dbo].[RECORDS]
ON GIFT.CONSTIT_ID LIKE RECORDS.ID
WHERE ([DTE] BETWEEN '2/7/2015' AND '2/8/2015')
AND GIFT.CONSTIT_ID IN (
SELECT CONSTIT_ID FROM re7.dbo.Gift GROUP BY CONSTIT_ID HAVING COUNT(*) = 1
) /* another option is to add a subquery to the query you already had */
ORDER BY [DATEADDED] DESC
This solution simply selects all the constituents who have made only one donation and then joins to that, thereby limiting the result set.
SELECT
r.[CONSTITUENT_ID]
,r.[FIRST_NAME]
,r.[LAST_NAME]
,[DATEADDED]
,[DTE]
,[Amount]
,[REF]
,[TYPE]
FROM
(select [CONSTIT_ID] from [re7].[dbo].[GIFT] group by [CONSTIT_ID] having count([CONSTIT_ID]) = 1) g1
inner join [re7].[dbo].[GIFT] g
on g.[CONSTIT_ID] = g1.[CONSTIT_ID]
INNER JOIN [re7].[dbo].[RECORDS] r
ON g.CONSTIT_ID LIKE r.RECORDS.ID
WHERE ([DTE] BETWEEN '2/7/2015' AND '2/8/2015')
ORDER BY [DATEADDED] DESC

How to avoid conditional multiple SELECT in a query

I have this simple SQL
SELECT
(CASE
WHEN
(SELECT
Name
FROM
Customers
WHERE
Customers_id = Customer) IS NOT NULL
THEN
(SELECT
Name
FROM
Customers
WHERE
Customers_id = Customer)
ELSE Customer
END) AS Customer,
DateStart,
ProgramsRun.Programs_id,
RunInSeconds,
SwSQL,
SwProgram,
Name AS ProgramName
FROM
ProgramsRun
LEFT JOIN
Programs ON ProgramsRun.Programs_id = Programs.Programs_id;
My question is how can I avoid make two same SELECT statements: one as condition and other as a value selection. I know that I can create a temporary variable, but this forces me to use stored procedures or temporary tables. Is there a simple way to avoid this?
You could use IFNULL like this:
IFNULL((SELECT
Name
FROM
Customers
WHERE
Customers_id = Customer),Customer)
Or COALESCE like this:
COALESCE((SELECT
Name
FROM
Customers
WHERE
Customers_id = Customer),Customer)
Reference:
COALESCE(value,...)
IFNULL(expr1,expr2)
Try this
SELECT
IsNull(Name,Customer)
AS Customer,
DateStart,
ProgramsRun.Programs_id,
RunInSeconds,
SwSQL,
SwProgram,
Name AS ProgramName
FROM
ProgramsRun
LEFT JOIN
Programs ON ProgramsRun.Programs_id = Programs.Programs_id;
You can rewrite your query by using join
SELECT
COALESCE(c.Name,Customer) AS Customer,
DateStart,
ProgramsRun.Programs_id,
RunInSeconds,
SwSQL,
SwProgram,
Programs.`Name` AS ProgramName
FROM ProgramsRun
LEFT JOIN Programs ON ProgramsRun.Programs_id = Programs.Programs_id
LEFT JOIN Customers c ON c.Customers_id = Customer;

JOINing Three SQL Tables?

I have a working SQL query, but I need to grab another piece of data from a third table in the query for ease of use, but have been unable to grab it.
Every table is basically tied together by tenant_id
(I apologize for the bad structure, I didn't create the DB)
TABLE: tenant_statements
tenant_id balance property date
TABLE: leases
lease_id tenant_id property unit_number
TABLE: tenants
tenant_id first_name last_name global_comment
My current query:
SELECT *
FROM tenant_statements t
INNER JOIN (
SELECT *
FROM leases
GROUP BY tenant_id
ORDER BY lease_id
)l ON t.tenant_id = l.tenant_id
WHERE t.date = '$date'
AND t.property = '$property'
ORDER BY t.balance DESC
This give's me the appropriate response for joining the two tables: leases and tenant_statements. $date and $property are set via a PHP variable loop and used for presentation.
What I am attempting to do is also grab tenants.global_comment and have it added each result.
the ideal output will be:
tenant_statements t: t.balance, t.date
leases l: l.property, l.unit_number
tenants x: x.first_name, x.last_name, x.global_comment
All in one query.
Can anyone point me in to the right direction? Thank you!
How about something like
SELECT *
FROM tenant_statements t INNER JOIN
(
SELECT *
FROM leases
GROUP BY tenant_id
ORDER BY lease_id
)l ON t.tenant_id = l.tenant_id INNER JOIN
tenants ts ON t.tenant_id = ts.tenant_id
WHERE t.date = '$date'
AND t.property = '$property'
ORDER BY t.balance DESC
Although each join specification joins only two tables, FROM clauses can contain multiple join specifications. This allows many tables to be joined for a single query.
SELECT t.tenant_id,
t.balance,
l.unit_number,
l.property
x.first_name, x.last_name, x.global_comment
fROM tenant_statements t
INNER JOIN leases l ON l.tenant_id = t .tenant_id
INNER JOIN tenants x on x.tenant_id = t.tenant_id