This question already has an answer here:
mysql don't count row twice if column data is duplicated
(1 answer)
Closed 9 years ago.
i have a a table called ptb_profile_views;
id | profile_id | viewed_profile | date
1 1 5
2 1 5
3 1 5
4 2 5
5 3 5
ok so in this example users 1,2 ans 3 are checking out user 5's profile,
the mysql i've got here is suppose to count the number of views a user has got, but where user 1 has checked out user 5 several times i do not want to return duplicate rows,
so instead of saying user 5 has been viewed 5 times, they will have only actually been viewed 3 times because i only want to count distinct values.
heres my mysql can someone please help me:
function check_profile_views() {
global $connection;
global $_SESSION;
$query = "SELECT COUNT(profile_id) FROM ptb_profile_views WHERE viewed_profile_id=".$_SESSION['user_id']." AND profile_id!='0'";
$check_profile_views_set = mysql_query($query, $connection);
confirm_query($check_profile_views_set);
return $check_profile_views_set;
}
the php:
$check_profile_views_set = check_profile_views();
while ($views = mysql_fetch_array($check_profile_views_set)) {
?>
<? echo"". $views['COUNT(profile_id)'] ."";?> viewed your profile
just add DISTINCT
SELECT COUNT(DISTINCT profile_id) totalCOUNT FROM ptb_profile_views...
and echo the alias,
$views['totalCOUNT']
SQLFiddle Demo
Related
This question already has answers here:
Return row only if value doesn't exist
(2 answers)
Search with comma-separated value mysql
(1 answer)
Closed 1 year ago.
Currently have hit a mental wall in my project. Brief summary. We have a table for completed courses on our site. Courses can be put in a plan. Trying to build a CSV export report that will show incompletions/completions so a manager can see progress for their environment and thus get with the employee to finish the plan.
Reports Table:
ID|UID|CID|Completed Date|
1 | 1 |78 |09-14-2021
2 | 1 |79 |09-14-2021
3 | 1 |75 |09-14-2021
4 | 1 |76 |09-14-2021
5 | 1 |77 |09-14-2021
Course table:
ID|NAME | credits | some other info
78|test
79|test2
75|test3
76|test4
77|test5
80|test6
Plan Table:
ID| Courses
8 | 75,76,77,78,79,80
I have the report generating all completions accurately my issue is when it doesn't exist in the completed table since the user hasn't finished it.
I use an if(isset reports.id) to dump info and an else statement to change the date to "incomplete"
My issue is populating the name for that course on the report. I'm not sure of how to check against data that doesn't exist. So in this example the course array would be [78,79,75,76,77,80] but the reports table only has completions for 75,76,77,78,79. The else statement is dumping $x[0] which the first result is "test". So I know my logic is wrong. But for the life of me can't think of the correct way to get the right information.
I need the else state ment to dump the remaining courses that aren't represented in the reports table as they are not complete. Any ideas?
Report Looks like this
Query for $courses array
"SELECT id, name, credits FROM `courses` WHERE id IN (78,79,75,76,77,80) ORDER BY id")
$courses[] = array($course_data['course_name'], $course_data['credits'],$course_data['id']);
//$exportdata is my SQL pull for all info.
if (isset($exportdata['reports.id'])) {
$completeddate = $exportdata['completed_date'];
$credit = $exportdata['credits'];
$coursename = $exportdata['course_name'];
} else {
foreach ($courses as $x) {
$credit = "-";
$completeddate = 'Incomplete';
$coursename = $x[0];
}
}
Excel function dumps $name, $email, $coursename, $completeddate, $credits in a row.
I have a query:
<?php
$results = $dbConn->select("SELECT entryA, entryB FROM table");
/**
Displays the rows on $results (entryA, entryB)
1 7
8 5
4 3
5 8
7 1
3 4
**/
$results = $dbConn->select("SELECT entryA, entryB FROM table ORDER BY ?");
/**
The correct output must be: (entryA, entryB)
1 7
7 1
8 5
5 8
4 3
**/
?>
How can i possible to order two columns that equal/match to each other ids in a different row?
Thanks in advance.
Yes, it is. For example
SELECT entryA, entryB FROM table ORDER BY entryA*entryA+entryB*entryB
-in my samples I'm supposing you have both pair variants, i,e {1,7} and {7,1}, for example.
This will group same pairs independent of elements order, but you may wish to have additional order condition - then simply add it to ORDER BY clause
I have the string $niveis with the following values (example):
3,8,10
Using this string, I need to count the number of rows in table content, where the access matches any of these 3 values.
For example, if table content is:
id access
1 2
2 3
3 3
4 7
5 8
6 9
7 10
8 10
Should return 5.
I tried the following query in PHP:
$query="SELECT count(id) FROM #__content WHERE access =$niveis";
But it isn't working, can anyone help?
You can use IN keyword
SELECT COUNT(id)
FROM #__content
WHERE access IN ($niveis)
You can use find_in_set():
select count(id)
from #__content
where find_in_set(access, $niveis) > 0;
Please consider the following "tweets" table:
tweet_id user_id text
----------------------------
1 1 lorem ipsum
2 1 lorem ipsum
3 2 pear
4 1 dolor
5 3 foo
6 1 dolor
7 1 dolor
8 3 bar
9 3 baz
10 4 happy
11 4 happy
12 2 apple
13 3 foo
14 4 happy
In reality, the table contains millions of tweets from about 80,000 users. Many of there users are spam accounts, but they are hard to identify by hand. As a rule of thumb, spam accounts post the same message at least 3 times. That's why I want to fill the following tables, "duplicates" on the left and "duplicates_tweets" on the right:
duplicate_id user_id text cnt duplicate_id tweet_id
-------------------------------------- ----------------------
1 1 lorem ipsum 2 1 1
2 1 dolor 3 1 2
3 2 pear 1 2 4
4 2 apple 1 2 6
5 3 foo 2 2 7
6 3 bar 1 3 3
7 3 baz 1 4 12
8 4 happy 3 5 5
5 13
6 8
7 9
8 10
8 11
8 14
I can now very easily sort on cnt for instance, and see which users post the most duplicate messages. My question however, is how to go about this most efficiently. In other words: what query would be most efficient to fill these tables? And is it possible with just SQL or should I use PHP as an intermediary, for instance to take a tweet from the "tweets" database, scans for duplicates, fills the tables, and moves on to the next tweet? I'm afraid this would take ages to finish, so any help is greatly appreciated!
Probably, you could sort the table "tweets" by user_id and then by text:
SELECT * FROM tweets ORDER BY user_id DESC, text DESC
Afterwards you can iterate over the results in PHP:
<?php
// ...
$lastuser = -1;
$lasttext = "";
$ids = array();
while ($row = mysql_fetch_assoc($result)) {
if($row['user_id'] != $lastuser || $row['text'] != $lasttext) {
$ids = array();
}
$ids[] = $row['id'];
if(count($ids) >= 3) {
// flag items as spam
}
$lastuser = $row['user_id'];
$lasttext = $row['text'];
}
?>
If you use indexes in your MySQL database, you should be able to process N tweets in approximately N*log(N).
You can use the REPLACE function in MySQL to UPDATE or INSERT a new row based on the key:
REPLACE duplicates
SELECT user_id, text
FROM (SELECT user_id, text, count(1) as count
FROM tweets
GROUP BY user_id, text
HAVING count(1) > 2))
I agree with what #MichaelRushton and #Kosta answered but I am wondering if you shouldn't need another table at all? If you build the query, you can ask the first table for the knowledge you are seeking. I especially like the trigger.
Do you just want to pull out a list of possible spam tweets? Try this:
SELECT
user_id,
text,
COUNT(DISTINCT tweet_id)
FROM
tweets
GROUP BY
user_id,
text
HAVING
COUNT(DISTINCT tweet_id) >= 3
You can then use PHP to iterate over the result and INSERT/UPDATE a duplicate_tweets table (although as Chris K mentioned, do you really need a duplicate_tweets table when you can just use this query?).
Before you insert new tweet, check tweets table whether such tweet already exists. If so, insert tweet and insert it in duplicates and duplicates_tweets tables. Or use triggers on insert for tweets table.
The table fields and its data:
auto_id user_id file_id
1 1 1
2 1 13
3 1 14
4 4 1
5 5 1
6 8 18
7 8 51
8 8 31
And what I want is:
userFiles[user_id] = 'file_id';
E.g:
userFiles[1] = '1,13,14';
userFiles[4] = '1';
userFiles[5] = '1';
userFiles[8] = '18,51,31';
Thank you very much!!
SELECT user_id, GROUP_CONCAT(file_id)
FROM yourtable
GROUP BY user_id
is the easy way to do it, if there aren't too many records - group_concat has a length limit of 1024 bytes (default, but is configurable).
The SQL query you can use is straightforward for each ID:
"select file_id from TABLE where user_id = " . $user_id;
Load your answers into an array, then:
$string = implode(",",$answers);
Put the whole thing in a for loop around your user_id and assign to your userFiles array.