I want to do 'union all' 2 tables. Because of this, I wrote the code below:
$query = "SELECT * FROM (SELECT * FROM news WHERE site_id = '1'
UNION ALL
SELECT * FROM all_news)
ORDER BY date DESC";
$news = mysqli_query($con, $query);
while($new = mysqli_fetch_object($news))
{
echo '- ' . $new->baslik . '<br>';
}
However, I got the error like that:
Warning: mysqli_fetch_object() expects parameter 1 to be
mysqli_result, boolean given in /../XAMPP/../../../index.php on line
19
Line 19 is while's line...
How can I fix it? I want to union 2 table, order by date all limit 10...
EDIT:
news table:
id | site_id | title | date (timestamp)
all_news table:
id | title | date (timestamp)
EDIT:
The problem was solved. I learned, if we want to use union or union all, our tables have to have same column number.
To union these 2 tables you will have to add an extra dummy column to the Query of the shorter table so the rules of UNION are met.
You dont need to add a real column to the schema for that table!
So if the tables are
News table:
id | site_id | title | date (timestamp)
all_news table:
id | title | date (timestamp)
Then the query can be written like this
SELECT id, site_id, title, date FROM news WHERE site_id = '1'
UNION ALL
SELECT id, 0, title, date FROM all_news
Note I added a dummy column to the select list of the all_news table so that the column count and the datatypes of each column match each other.
You can use any number you like other than 0, so pick one that identifies this as data you dont want to process, or it can be used to identify the rows from all_news by setting a specific value.
Note: I assumed site_id was an integer, if its a text then use '0' for example or 'IGNORE ME'.
Related
I have the table:
id | date_submitted
1 | 01/01/2017
1 | 01/02/2017
2 | 01/03/2017
2 | 01/04/2017
I'm looking for the correct SQL to select each row, limited to one row per id that has the latest value in date_submitted.
So the SQL should return for the above table:
id | date_submitted
1 | 01/02/2017
2 | 01/04/2017
The query needs to select everything in the row, too.
Thanks for your help.
You can find max date for each id in subquery and join it with the original table to get all the rows with all the columns (assuming there are more columns apart from id and date_submitted) like this:
select t.*
from your_table t
inner join (
select id, max(date_submitted) date_submitted
from your_table
group by id
) t2 on t.id = t2.id
and t.date_submitted = t2.date_submitted;
Note that this query will return multiple rows for an id in case there are multiple rows with date_submitted equals to max date_submitted for that id. If you really want only one row per id, then the solution will be a bit different.
If you just need id and max date use:
select id, max(date_submitted) date_submitted
from your_table
group by id
I am struggling to get this MySQL query to work. I have two tables:
Table 1
TYPE | NAME | LAT | LON | ICON
Table 2
ID | UID | NAME | LAT | LON | ICON
I am trying to select all results from Table 1 and only select some results from Table 2. I am trying to apply a WHERE clause to Table 2 but it doesn't seem to work.
I read the documentation and it said for a UNION to work the number of columns have to be the same. How can I then only select the same number of columns from both tables to be returned but filter the second table by a column only found on that table?
My (pseudo)Query:
(SELECT name,lat,lon,icon
FROM Table1)
UNION
(SELECT name,lat,lon,icon
FROM Table2
WHERE uid ="1")
SELECT * FROM table1
UNION
SELECT
NULL AS `type`,
`name`,
`lat`,
`long`,
`icon`
FROM table2 WHERE uid = 1
http://www.sqlfiddle.com/#!9/0a942/8
This selects everything from table1, and only where uid = 1 from table2.
An UNION can only be performed if both row sets have the exact same columns. Since there is no type column in table2, we select a NULL and name it type so we can do the UNION.
i have a table like this
id(pk)|product_id(fk)|serial(varchar)|status(varchar)
1 | 2 | e098 | sold
2 | 2 | e008 | faulty
what i need to extract is:
array(faulty=>1,sold=>1)
i i can do it with a complex query, is there any SIMPLE query which can help?
i tried this:
SELECT COUNT(id) as product_details.status FROM product_details WHERE product_id=2 GROUP BY status which didn't work.
(ab)Use mysql's auto-typecasting:
SELECT SUM(status='sold') AS sold, SUM(status='faulty') AS faulty
FROM ...
the boolean result of status='sold' will be typecast to integer 0/1 and then summed up.
The other option is just to do a regular query and then do the pivoting in client-side code:
SELECT id, status, COUNT(status) AS count
FROM ...
GROUP BY id, status
and then
while(... fetch ...) {
$results[$row['id']][$row['status']] = $row['count'];
}
You want to query status as well like this.
SELECT status, COUNT(id) as count FROM product_details WHERE product_id=2 GROUP BY status
i need to get the latest order (from our custon admin panel). here's my query:
select *
from order
left join customer
on (customer.id = order.fk_cid)
where date = curdate()
order by time desc
limit 1;
this output everything from orders and customers which i need except 1 therefore that is why i use the *
here's my table structure:
order table:
id, fk_cid, date, time
customer table:
id, name, lastname, street, city, zip, country, phone, email, lastlogin
now, in my php i have:
$result = mysql_query("
select *
from `order`
left join customer
on (customer.id = order.fk_cid)
where date = curdate()
order by time desc
limit 1");
$row = mysql_fetch_assoc($result, MYSQL_ASSOC);
at this point my order is not correct, why?
Your customers.id is overwriting the order.id because you are using the same column name.
select *
from `order`
left join customer on (customer.id = order.fk_cid)
where date = curdate() order by time desc limit 1;
+------+--------+------------+----------+------+-------+------
| id | fk_cid | date | time | id | name | ....
+------+--------+------------+----------+------+-------+------
| 1 | 2 | 2011-11-30 | 07:01:23 | 2 | asasd | ....
+------+--------+------------+----------+------+-------+------
1 row in set (0.03 sec)
As you can see in this example you have two id, so PHP when retrieve the data using mysql_fetch_assoc it overwrites the second id because it's the same key in the array. To fix this, you will have to specify the columns in your query:
select `order`.id AS order_id, customer.id AS customer_id, customer.name /* etc... */
This will output:
Also, I recommend to use different name for your tables and fields. order, date, time since they are reserved word (in case you forget for use the ` ).
Array
(
[order_id] => 1
[customer_id] => 2
// etc...
)
Also here's a topic you should read: Why is SELECT * considered harmful?
Assuming this table is ordered by date
id | date | customer
3 | 2009-10-01| Frank
1 | 2010-10-11| Bob
4 | 2010-11-01| Mitchel
2 | 2010-11-02| Jim
I would like to make a query so that knowing ID = 4 the resulting rows are
$row[0]['id'] == 1 //previous
$row[1]['id'] == 4 //most recent/current
$row[2]['id'] == 2 //next
A mysql only solution would be best, but if there is an elegant php solution that would be cool as well.
As the table IS sorted by date column, you can run following queries to get it:
For previous row:
select * from tablename where `date` < (select `date` from tablename where id=4) order by `date` desc limit 1
For current row:
select * from tablename where id=4
For next row:
select * from tablename where `date` > (select `date` from tablename where id=4) order by `date` asc limit 1
Output: These three queries return the result (one by one) as following:
id date customer
1 2010-10-11 Bob
4 2010-11-01 Mitchel
2 2010-11-02 Jim
Since you are ordering by date, but basing the row you want the adjacent rows on id, your going to have to do 2 queries. The first to determine the date for the ID you have selected, the second to get the adjacent rows.
Step 1 - Get the date
Select date
FROM yourtable
WHERE id = 4
Step 2 - Get all the rows
SELECT *
FROM yourtable
WHERE date IN ( (select MAX( date ) from yourtable where date < $datefromquery1)
, $datefromquery1
, (select MIN( date ) from yourtable where date > $datefromquery1)
)
The LIMIT function can take two arguments, an offset and a number of rows to return. In your case, you want the offset to be (the number of rows with dates before the desired row) - 1, or in this case 2 - 1 = 1, and the number of rows to be three. So the SQL you want is
SELECT * FROM customers ORDER BY date ASC LIMIT 1,3;
and the number "1" will be the result of the query
SELECT COUNT(*)-1 FROM customers WHERE date > "2010-11-01";
I don't believe MySQL will let you use a subselect or function value as the argument of LIMIT, so you'll have to store that using PHP and construct the next query that way.