SQL queries are still my weakest point, so here I am with yet another SQL question.
Imagine I have two tables: auctions and bids. Table auctions contains my auctions and table bids contains the list of bids for each auction.
Now I'm selecting values like this:
SELECT
`auction_title`,
`auction_seo_title`,
`auction_description_1`,
`auction_unixtime_expiration`,
`auction_startPrice`,
MAX(`bids`.`bid_price`) as `bid_price`
FROM
`auctions`
LEFT JOIN `bids` ON `auctions`.`auction_id`=`bids`.`bid_belongs_to_auction`
ORDER BY
`auction_unixtime_expiration`
ASC
LIMIT 5
The query works, but it's got a little catch to it: It selects only those auctions, which have at least one corresponding value inside the bids table. That means that if I have a new auction, which has no bids yet, the query doesn't return this auction, but I want it too!
I believe this is a very simple problem for anyone with at least above average SQL skills. I hope someone like that comes around :) Thanks in advance!
SELECT
`auction_title`,
`auction_seo_title`,
`auction_description_1`,
`auction_unixtime_expiration`,
`auction_startPrice`,
MAX(`bids`.`bid_price`) as `bid_price`
FROM
`auctions`
LEFT JOIN `bids` ON `auctions`.`auction_id`=`bids`.`bid_belongs_to_auction`
GROUP BY `auction_id`
ORDER BY `auction_unixtime_expiration` ASC
Give that a try. Assuming that works, you can add your LIMIT on to the end.
Related
I've got a SQL statement:
SELECT AVG(`totalhours`)/5 AS `average`,* FROM `report_signout` JOIN `employee` ON `employee`.`username`=`report_signout`.`username`
However it's not working. Basically I need to calculate the average total hours an employee has been on the premises in any one week, the assumption is accepted that the office is only open 5 days a week. The total hours are coming from the table report_signout which I need to join on the username of the employee table so I can produce an outcome where I can then list the Firstname and Lastname of the employee along with the average hours on a web page. That last part is done in PHP which I already know how to do. I just need to see where I'm going wrong with the SQL statement.
If someone could point out to me please or give me a bit of help it would be much appreciated, thanks!
MySQL does not really know what totalhours is. As you are referencing more than one table, a table is not assumed, so you need to declare what to average by defining the reference as:
`table name`.`column name`
This is true for most if not all MySQL built in functions. Use absolute declarations (ie those with table and column names both defined, as above) as much as possible.
SELECT AVG(`report_signout`.`totalhours`)/5 AS `average`,
`report_signout`.*, `employee`.*
FROM `report_signout`
INNER JOIN `employee` ON `employee`.`username` = `report_signout`.`username`
As a small aside, try and avoid vague JOIN referencing instead using a complete JOIN reference, which states the type of JOIN rather than an assumption.
Also try to avoiding using * selection instead stating each column you wish to call.
I am sure this question has already been answered, but I can't find it or the answer was too complicated. I am new to SQL and am not sure how to word this generically.
I have a mySQL database of software installed on devices. My query to pull all the data has more fields and more joins, but for brevity I just included a few. I need to add another dimension to create a report that lists every case where a device has more than one installation of software from the same product family.
sample
Right now I have code kind of like this and it is not doing what I need. I have seen some info on exists but the examples didn't account for multiple joins so the syntax escapes me. Help?
select
devices.name,
sw_inventory.product,
products.family_name,
sw_inventory.ignore_usage,
from sw_inventory
inner join products
on sw_inventory.product=products.product_name
inner join devices
on sw_inventory.device_name=devices.name
where sw_inventory.ignore=0
group by devices.name, products.family_name
There are plenty of answers out there on this topic but I definitely understand not always knowing terminology. you are looking for how to find duplicates values.
Basically this is a two step process. 1 find the duplicates 2 relate that back to the original records if you want those. Note the second part is optional.
So to literally find all of the duplicates of the query you provided
ADD HAVING COUNT(*) > 1 after group by statements. If you want to know how many duplicates add a calculated column to count them.
select
devices.name,
sw_inventory.product,
products.family_name,
sw_inventory.ignore_usage,
NumberOfDuplicates = COUNT(*)
from sw_inventory
inner join products
on sw_inventory.product=products.product_name
inner join devices
on sw_inventory.device_name=devices.name
where sw_inventory.ignore=0
group by devices.name, products.family_name
HAVING COUNT(*) > 1
this is my query from my source code
SELECT `truyen`.*, MAX(chapter.chapter) AS last_chapter
FROM (`truyen`)
LEFT JOIN `chapter` ON `chapter`.`truyen` = `truyen`.`Id`
WHERE `truyen`.`title` LIKE \'%%\'
GROUP BY `truyen`.`Id`
LIMIT 250
When I install it on iFastnet host, It cause over 500,000 rows to be examined due to the join, and the query is being blocked (this would used over 100% of a CPU, which ultimately would cause server instability).
I also tried to add this line before the query, it fixed the problem above but lead to another issue making some of functions can not run correctly
mysql_query("SET SQL_BIG_SELECTS=1");
How can I fix this problem without buying another hosting ?
Thanks.
You might be looking for an INNER JOIN. That would remove results that do not match. I find INNER JOINs to be faster than LEFT JOINs.
However, I'm not sure what results you are actually looking for. But because you are using the GROUP BY, it looks like the INNER JOIN might work for you.
One thing I would recommend is copy and paste the query that it generates into SQL with DESCRIBE before it.
So if the query ended up being:
SELECT truyen.*, MAX(chapter.chapter) AS last_chapter FROM truyen
LEFT JOIN chapter ON chapter.truyen = truyen.Id
WHERE truyen.title LIKE '%queryString%'
You would type:
DESCRIBE SELECT truyen.*, MAX(chapter.chapter) AS last_chapter FROM truyen
LEFT JOIN chapter ON chapter.truyen = truyen.Id
WHERE truyen.title LIKE '%queryString%'
This will tell you if you could possibly ad an index to your table to JOIN on faster.
I hope this at least points you in the right direction.
Michael Berkowski seems to agree with the indexing, which you will be able to see from the DESCRIBE.
Please look if you have indexes on chapter.chapter and chapter.truyen. If not, set them and try again. If this is not successful try these suggestions:
Do you have the possibility to flag permanently on insert/update your last chapter in a column of your chapter table? Then you could use it to reduce the joined rows and you could drop out the GROUP BY. Maybe in this way:
SELECT `truyen`.*, `chapter`.`chapter` as `last_chapter`
FROM `truyen`, `chapter`
WHERE `chapter`.`truyen` = `truyen`.`Id`
AND `chapter`.`flag_last_chapter` = 1
AND `truyen`.`title` LIKE '%queryString%'
LIMIT 250
Or create a new table for that instead:
INSERT INTO new_table (truyen, last_chapter)
SELECT truyen, MAX(chapter) FROM chapter GROUP BY truyen;
SELECT `truyen`.*, `new_table`.`last_chapter`
FROM (`truyen`)
LEFT JOIN `new_table` ON `new_table`.`truyen` = `truyen`.`Id`
WHERE `truyen`.`title` LIKE '%queryString%'
GROUP BY `truyen`.`Id`
LIMIT 250
Otherwise you could just fetch the 250 rows of truyen, collect your truyen ids in an array and build another SQL Statement to select the 250 rows of the chapter table. I have seen in your original question that you can use PHP for that. So you could merge the results after that:
SELECT * FROM truyen
WHERE title LIKE '%queryString%'
LIMIT 250
SELECT truyen, MAX(chapter) AS last_chapter
FROM chapter
WHERE truyen in (comma_separated_ids_from_first_select)
A small question may be it is silly but I am not getting idea how to solve this problem
select * from customers where id in(select assigned from users where username='test');
in the above query
select assigned from users where username='test'
this returns 1,2
but the condition where in doesnot work which should be like below
select * from customers where id in(1,2);
this is not the exact output i am just guessing that it might be this way. which is not so the problem is occuring.
i am getting only one row that is corresponding to 1
so help me figuring this out.
please check the sqlfiddle below:
http://sqlfiddle.com/#!2/95c28/2
thanks
SELECT DISTINCT c.*
FROM customers c
JOIN users u ON FIND_IN_SET(c.id, u.assigned) IS NOT NULL
Putting comma-separated values is a bad idea in relational databases, it makes everything more complicated. You should use a relation table instead, so you can write a normal equality join. The above query cannot be indexed, so it will be very innefficient if the tables are large.
SQLFIDDLE
if select assigned from users where username='test' returns 1,2. This means your customer table contains only Id=1.
Well this will be hard to explain but ill do my best
The thing is i have 4 tables all with a specific column to relate to eachother.
1 table with users(agent_users) , 1 with working hours(agent_pers), 1 with sold items(agent_stat),1 with project(agent_pro)
the user and the project table is irrelevant in the issue at hand but to give you a better understanding why certain tables is included in my query i decided to still mention them =)
The thing is that I use 2 pages to insert data to the working hour and the sold items during that time tables, then i have a third page to summarize everything for current month, the query for that is as following:
SELECT *, SUM(sv_p_kom),SUM(sv_p_gick),SUM(sv_p_lunch) FROM ((
agent_users
LEFT JOIN agent_pers ON agent_users.sv_aid = agent_pers.sv_p_uid)
LEFT JOIN
agent_stat ON agent_pers.sv_p_uid = agent_stat.sv_s_uid)
LEFT JOIN
agent_pro ON agent_pers.sv_p_pid=agent_pro.p_id
WHERE MONTH(agent_pers.sv_p_datum) =7 GROUP BY sv_aname
so the problem is now that i dont want sold items from previous months to get included in the data received, i know i could solve that by simple adding in the WHERE part MONTH(agent_stat.sv_s_datum) =7 but then if no items been sold that month no data at all will show up not the time or anything. Any aid on how i could solve this is greatly appreciated. if there's something that's not so clear dont hesitate to ask and ill try my best to answer. after all my english isn't the best out there :P
regards
breezer
Fair enough :) -- put the condition as a second condition in your JOIN clause. ON (agent_pers.sv_p_uid = agent_stat.sv_s_uid AND agent_stat.sv_s_datum = 7)
Is your data such that you could add (MONTH(agent_stat.sv_s_datum) =7 OR agent_stat.sv_s_datum IS NULL) to the WHERE clause?