I have a brands table and posts table.
Below is their schema
Brands :
brands_id, friendly, short ,followers, created, location, brandID,
handle, url, pic, utcOffset, posts, engagements, engagedUser,
etc(sufficient for current question)
Posts :
post_id, brandID, postID, handle, posted, content, postType, comments,
etc (sufficient for current question)
where postType= link, status,video,question,poll,etc
Now I have hardcoded pivoting with the following query:
select b.friendly,
sum(case when p.postType='link' then 1 else 0 end) as 'link',
sum(case when p.postType='video' then 1 else 0 end) as 'video',
sum(case when p.postType='status' then 1 else 0 end) as 'status',
sum(case when p.postType='photo' then 1 else 0 end) as 'photo',
count(p.postType)
from brands b, posts p
where b.handle
in ('chevroletcanada','dodgecanada')
and p.handle=b.handle
and date(p.posted)
BETWEEN "2013-06-02" and "2013-08-11"
group by b.friendly
But in the above query I have used types of postType statically, i.e for links, status, video, photo. Now if a new postType is added to the posts table, this won't work, as I would have to change the query too. Also if existing values in postType is deleted, then too the query have to be changed again.
My question is how can I achieve this dynamically so that when new postType values for instance tweet is added in posts table then tweet will show up in the result sets as well. And the same for deletion of any postType.
If you haven't understood question, please inform me.
I have read the below posts, but unable to figure out:
MySQL or PHP Turning rows into columns dynamically
MySQL pivot table query with dynamic columns
Thanks in advance!!
This is the solution for the above problem. Dynamic pivot can be achieved like this:
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'sum(case when postType = ''',
postType,
''' then 1 end) as `',
postType, '`')
) INTO #sql
FROM posts;
SET #sql = CONCAT('SELECT b.friendly, count(p.postType), ', #sql, ' from brands b, posts p where b.handle in ("dodgecanada","chevroletcanada") and p.handle=b.handle
and date(p.posted) BETWEEN "2004-08-11" and "2013-09-11" group by b.friendly');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
The above query displays right results in SQL interface HeidiSQL. But returns:
"#1243 - Unknown prepared statement handler (stmt) given to EXECUTE" message in phpMyAdmin.
Can anyone tell me why is this so? Is 'prepared' statement not supported in Mysql? or is there any issue in phpMyAdmin running prepared statements.
How can I overcome this in phpMyAdmin?And can anyone tell me how can I do this in PHP? Thanks!!
Related
So my (MySQL) Looks like so:
'Table' -> Column : p_id, name, rank, branch(enum (Air Force, Army, Marines, Navy, None)), billet, etc etc
So I am trying to grab the branch with the lowest amount of members and trying to avoid getting anything from (None or Navy 'at this time') The main branches I want to grab stuff from would be Air Force, Army, and Marines. Showing the lowest amount of personnel / members from that branch
So this is what I have done
$stats['lowest'] = DB::run('SELECT MIN(branch) as min_branch FROM personnel')->fetchColumn();
Recruits should go to : <?php echo $stats['lowest']; ?>
It shows Air Force even though it has 3 members in it while Army and Marines haves 0 with the 'branch' title
You are probably looking for a group and count as a sub query
SELECT
`a`.`branch`
FROM(
SELECT
`personnel`.`branch`,
COUNT(*) AS `c`
FROM
`personnel`
WHERE
`personnel`.`branch` IN('Air Force','Army','Marines')
GROUP BY
`personnel`.`branch`
ORDER BY
`c` ASC
) AS `a`
LIMIT 1
BUT
Since you are trying to get Army and Marines which don't have any records... they wont be included in your query. So any result that is returned will never give you a 0 value.
It appears you are trying to count records that dont exist... which wont work without setting up a database view (although someone else might have a better answer)
I ran into an error I cant seem to come out of.
am not too good with unions
I want to loop through 4 different tables(using union all) and manipulate their values to fit my needs.
I also need to use single 'ORDER by Date DESC' (Date are integer values) for the whole union all, so that I can arrange the output in a pattern,
when I add the 'order by date desc ' to it, code doesn't work . and when I remove it , the values of the second query are attached to the names of the first query, am sooo confused.
I tried "Select * from table_name where..... it idnt work in this case , that's why I had to bring out all table_names I need to the query,
Basically , I want to echo each value from the query uniquely when I need to,
any help is appreciated, thanks
<?php
$q114="(SELECT id AS id1,text_post AS text_post1,likes AS likes1
FROM timeline_posts WHERE email='$owner_email')
UNION ALL (SELECT pic_comment AS pic_comment2, comments AS comments2, date AS date2
FROM pictures WHERE email='$owner_email')
UNION ALL (SELECT image AS image3,likes AS likes3, comments AS comments3
FROM profile_pics WHERE email='$owner_email')
UNION ALL (SELECT likes AS likes4, comments AS comments4, date AS date4
FROM friends_timeline_post WHERE timeline_email='$owner_email')
ORDER BY 'date' DESC";
$pages_query=mysqli_query($connect,$q114);
while($fetch9=mysqli_fetch_assoc($pages_query))
{
print_r($fetch9['likes3'] );
//a lot of work to be done here
}
?>
For "unioning" the results of multiple selects and ordering those results by a column name across all the results of the multiple selects, column names must be the same in all selects.
You could add a column to all selects that would contain your "digit" in order to still be able to distinguish between let say "likes1" and "likes2" even if their column name is "likes" for all the selects that you "unioned".
Hello supposed to have a temporary table that having resultset like this:
And the month column is changing dynamically based on user input. Now I want my month column values (months) to become columns and under it was the amount and everything will be group by account_id.
I've searched every answers for this but I still can't get it. Here's my code but it is not returning accurately and I'm still lost here:
CREATE DEFINER=`root`#`localhost` PROCEDURE `test`()
BEGIN
SET group_concat_max_len=2048;
SELECT CONCAT('
SELECT account_id, month ',
GROUP_CONCAT('
GROUP_CONCAT(IF(amount=',QUOTE(amount),',value,NULL))
AS `',REPLACE(amount,'`','``'),'`'
), '
FROM tmp_results
GROUP BY account_id
')
INTO #sql
FROM (
SELECT account_id, month FROM tmp_results
) t;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Can someone help me step by step that I could understand it? PHP laravel step by step also are welcome. I'm a newbie developer. Thank you!
$query="SELECT title, max(postid) FROM post";
postid is a increasing numeric value (1,2,3...). At the moment, the highest value is 49, but It's pulling up 1. It seems to be ignoring the MAX statement.
otherwise everything else is working great.
That's not valid syntax, which engine is running it?
You either need:
SELECT title, max(postid) FROM post GROUP BY title;
to get multiple records, one for each title, showing the max postid for each title, or
SELECT max(postid) FROM post
to get the single max postid from the table.
If you want the highest postid and the title that goes with it, you need
SELECT TOP 1 title, postid FROM post ORDER BY postid DESC
or
SELECT title, postid FROM post ORDER BY postid DESC LIMIT 1
depending on your SQL engine.
One important thing is that the field that is used in MAX function should be INT Type
Then it will give accurate result:
SELECT title, max(postid) FROM post GROUP BY title
Postid should be an integer.
Have you tried:
SELECT title, max(postid) FROM post GROUP BY title
I would have expected whichever sql engine you are using to respond with an error without a group by clause in your statement. However, if the GROUP BY is in some way implied somewhere else in your code, you should remove 'title' from the select clause (since I would expect a 'title' to be associated with only one post anyway). In that case if you simply expect the max postid from the post table your statement should read:
SELECT max(postid) FROM post
I am currently running this query inside MySQL to check if the specified values exists
within the table associated with them.
SELECT COUNT(artist.artist_id), COUNT(album.album_id), COUNT(tracks.track_id)
FROM artist, album, tracks WHERE artist.artist_id = 320295 OR album.album_id = 1234 OR tracks.track_id = 809
The result I get from running this query is all 1, meaning that all the statements after the WHERE clause is true. To further check the query's reliability, I changed the tracks.track_ = 809 to 802, which I know does not match. However the results displayed are still all 1, meaning that they were all successfully matched even when I purposefully inserted a value which would not have matched.
How do I get it to show 1 for a match and 0 for no matches within the same query?
EDIT: I have inserted an image of the query running
What you do here is a join over three tables. You can see what happens, when you look at this SQL Fiddle.
In the first select, I have left out the count, to show how the join works. You can also see how the result set changes, when you modify the where clause from or to and as #RayPaseur suggested.
I guess, what you want, is really three separate queries
select 'artist' as type, count(artist_id) as count
from artist
where artist_id = 320295
union
select 'album', count(album_id)
from album
where album_id = 1234
union
select 'track', count(track_id)
from tracks
where track_id = 809
which becomes
TYPE COUNT
artist 1
album 1
track 1
Now, when you change track_id = 809 to track_id = 802, you will get
TYPE COUNT
artist 1
album 1
track 0
as a result.
SQL Fiddle for playing.
The "or" clause may be your issue here. If any of those WHERE clauses works, you will have a results set that is not empty. Maybe something like SELECT COUNT(*)... WHERE... AND... AND...
But it would be more helpful to see the entire PHP code set. And I would recommend running three different queries - not because it's technologically sophisticated, but just because it is easier to get it to work right the first time!