how ignore duplicate values without consider of their position in mysql? - php

I have this table with one column
A:
16654,16661
16661,16654
16670,16717
16717,16670
I want to have this: (ignore duplicate values without consider of their position)
16661,16654
16670,16717
is there any math function that operate between two number and have unique result?
actually i have this table ( name:class)
id second_code have_second_code
1 0 no
2 3 yes
3 2 yes
4 5 yes
5 4 yes
when "have_second_code" is "yes"
column second_code have a value!
id is primary
second code is from id column and there is a binary relation between them. now i need this output 2,3 and 4,5

SELECT rowone, rowtwo, rowonemillion FROM yourtable GROUP BY(nodupecolumn)

I suppose, that your query that produces this one-column-multiple-values-table uses GROUP_CONCAT(). In this case you need to do it like this:
SELECT DISTINCT GROUP_CONCAT(DISTINCT whatever_column ORDER BY whatever_column) FROM ...
Use the DISTINCT keyword two times. In GROUP_CONCAT(), so that duplicates are removed from the comma separated values, and one time outside of GROUP_CONCAT(), so that duplicate rows are removed. The ORDER BY in GROUP_CONCAT() is important, otherwise the outer DISTINCT won't detect duplicates. Also note, that (outer) DISTINCT works on the whole row, not just one column.

Related

How to count each item in array with sql

I have a user table which contain a membergroupids, and user table looks like this:
userid membergroupids
1 1,2
2 2,3
3 2,3,4
and I want to use sql to output a result like this
membergroupid count
1 1
2 3
3 2
4 1
I tried use SELECT membergroupids FROM user, then use php to loop through the result and get the count, but it works with small set of user table, but I have a really big user table, the select query itself will take more than 1min to finish, is there better way to do this?
There is a much better way to do it. Your tables need to be normalized:
Instead of
userid membergroupids
1 1,2
2 2,3
3 2,3,4
It needs to be
userid membergroupids
1 1
1 2
2 2
2 3
3 2
3 3
3 4
From here, it's a simple query to get the counts (assuming this table is called your_table:
select count(membergroupids) as numberofgroups, userid
from your_table
group by userid
order by userid
The real problem, then, is getting your tables normalized. If you only have 9 membergroupids, then you could use a like '%1%' to find all userids with membergroupid #1. But if you have 10, then it won't be able to distinguish between 1 and 10. And sadly, you can't count on the commas to help you distinguish because the number might not be surrounded by commas.
unless...
Create new field with group ids encapsulated by commas
you could create a new field and populate it with membergroupids and surround it with commas by using concat (check your database's docs). Something along this line:
update your_table set temp=concat(',', membergroupids, ',');
This could give you a table structure like so:
userid membergroupids temp
1 1,2 ,1,2,
2 2,3 ,2,3,
3 2,3,4 ,2,3,4,
Now, you have the ability to grab distinct member group ids in the new field, ie, where temp like '%,1,%' to find userids with membergroupid 1. (They will be encapsulated by commas) Now, you can manually build your new normalized table which I'll call user_member.
Insert membergroupid 1:
insert into user_member (userid,membergroupid) select userid,'1' from your_table where temp like '%,1,%';
You could make a php script that loops through all the membergroupids.
Keep in mind that like %...% is not very efficient, so don't even think about relying on this to do your count. It'll work, but it's not scalable. It would be much better to use this to build the normalized table.
It's easy to do your purpose IF the data structure is as like as below:
SELECT `membergroupids`, COUNT(`membergroupids`) as
CountOfMembergroupids FROM `TBL_TEST01` WHERE 1
GROUP BY `membergroupids`
ORDER BY `userid`
As you mentioned that you have to proceed with large amount of data..., I'd strongly suggest that you could revise your table structure as above...

How to retrieve count values as multiple columns using group by in single query in MySQL?

I am writing a complex MySQL query. My actual query is more complex than I mentioned below.
I have a table named example and columns are id, name, option_1, option_2 . Of course id column is PK . I want to retrieve like this:
SELECT `id`,`name`,count(`option_1`),count(`option_2`)
My problem is I want to use "GROUP BY `id`" for count(`option_1`) and "GROUP BY `name`" for count(`option_2`) respectively. Now I have to break down it into multiple code in my php code.
How can I achieve what I want in a single query?
What you're asking for doesn't make a ton of sense. You want option 1 grouped by id and option 2 grouped by name, and you want to show all four columns in one result set.
First of all, if id is a primary key, then the count will just be the number of rows in the table since there will be no duplicate ids.
Second, even if id wasn't a primary key, and there were duplicate values, the grouping is different, so the counts represented in your result set would be grouped incorrectly.
Given that id is a primary key, perhaps your intention is actually to get a total count of the rows in the table. Perhaps this query would suit your needs?
SELECT
name,
COUNT(option_2) AS options
FROM
example
GROUP BY
name
UNION ALL
SELECT
'Total' AS name,
COUNT(*) AS options
FROM
example
This should get you a count of all the option_2 values, grouped by name, with the final row having a name of 'Total' and the count being the total number of rows in the table.
Aside from that, I'm not sure you're going to find the answer you're looking for due to the problems you would encounter matching up groupings.

Mysql Join 2 Table and merge 2 Column, But remove Duplicate

I have 2 Table from where I want customerid, customername, comment and customercontactno.
I use Following query For Join 2 Table.
SELECT comment.id, comment.Kommentar, comment.Kunde,
CONCAT_WS('', customer.telefonPrivat, customer.TelefonMobil) AS Contact_Phone
FROM tbl_test_comment comment
LEFT JOIN tbl_test_customer customer
ON customer.id = comment.Kunde;
My First table is tbl_test_comment With following data
And tbl_test_customer
Result Of Above Query
ISSUE
When I run above query, Its working fine if one of two merged column is empty. But it merge data if data are in both row. I want to avoid one if both row have value.
Expected Output
concat_ws stands for "concatenate with separator", that is, add the strings together with the separator in between.
Instead, use the coalesce function, which returns the first non-null argument:
coalesce(customer.telefonPrivat, customer.TelefonMobil)
If an empty telephone number can be an empty string '' as well as null, you can use the more powerful case statement:
case
when length(customer.telefonPrivat) > 0 then customer.telefonPrivat
else customer.TelefonMobil
end

fetch the comma separate field in mysql query

My table id and skillid values are
1=>3
2 =>5
3 =>5,6,8
I have tried the query to fetch the value from my table
SELECT * FROM mytable WHERE skillid IN ('3', '5');
But i am getting only two rows, that was first and second row.
But i need the result three rows.
Thanks in advance.
The 'IN' comparison operator works like an equality operator. This:
expr IN ('3','5')
is equivalent to:
( expr = '3' OR expr = '5' )
That should be sufficient to explain why your query is not returning what you expect.
If your table has a character column that contains a comma separated list, like this:
id skill_id_list
-- -------------
1 3
2 5
3 5,6,8
Then one option, to search for a particular id value in the list is to make use of the MySQL FIND_IN_SET function. For example:
SELECT t.id
, t.skill_id_list
FROM mytable t
WHERE FIND_IN_SET('3', t.skill_id_list)
OR FIND_IN_SET('5', t.skill_id_list)
The MySQL FIND_IN_SET function is documented here:
https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_find-in-set
Of course, that's only one option. There are several other ways to get an equivalent result.
If there are no spaces in the skill_id_list column, then another option is to use a LIKE operator, but taking care to handle the edge cases.
There are four cases you would need to check for the id value appearing:
as the only one in the list
at the beginning of the list
in the middle of the list
at the end of the list
To explicitly handle those four cases, you could check each one, for example:
WHERE skill_id_list LIKE '3' -- only one in list
OR skill_id_list LIKE '3,%' -- beginning of list
OR skill_id_list LIKE '%,3,%' -- middle of list
OR skill_id_list LIKE '%,3' -- end of list
Or, another way to approach that is to turn all of those cases into the single "middle of the list" by just appending a comma to the beginning and end of the list, and then doing a single check, for example:
WHERE CONCAT(',',skill_id_list,',') LIKE '%,3,%'
Note that spaces embedded in the list could cause a row not to match. The MySQL REPLACE function can be used to remove spaces, replacing all spaces with an empty string, something like this:
WHERE CONCAT(',',REPLACE(skill_id_list,' ',''),',') LIKE '%,3,%'
NOTE
The preceding attempts to to answer the question you asked. The following addresses a fundamentally different (though closely related) issue, concerning the relational dataa model and normalization.
Repeating attributes in normalized relational model are represented in separate table. That's the normative relational model. We typically avoid storing comma separated lists, and instead implement a separate table to store the repeating attributes.
For example, if a job has multiple skills, we would typically create another table to hold the list of job skills:
CREATE TABLE job
( id INT NOT NULL PRIMARY KEY
, description VARCHAR(10)
);
CREATE TABLE job_skill
( job_id INT NOT NULL COMMENT 'FK ref job.id'
, skill_id INT NOT NULL COMMENT ''
, PRIMARY KEY (job_id, skill_id)
, FOREIGN KEY job_skill_FK1 (job_id) REFERENCES job (id)
);
We'd represent the data in your model as five separate rows:
job_skill
job_id skill_id
------ --------
1 3
2 5
3 5
3 6
3 8
That's the normative pattern.
To get back a list of job ids that require skills 3 or 5:
SELECT s.job_id
FROM job_skill s
WHERE s.skill_id in (3,5)
GROUP BY j.job_id
To get back a list of job ids that require skills 3 and 5, there's several ways to do that, for example:
SELECT s.job_id
FROM job_skill s
ON s.job_id = t
WHERE s.skill_id in (3,5)
GROUP BY j.job_id
HAVING COUNT(DISTINCT s.skill_id) = 2
If it's more convenient for your use case to get back a comma separated list as a string, you can use the GROUP_CONCAT aggregate function:
SELECT j.id AS job_id
, GROUP_CONCAT(s.skill_id ORDER BY s.skill_id) AS skill_id_list
FROM job j
LEFT
JOIN job_skill s
ON s.job_id = j.id
WHERE ...
ORDER BY ...
Please check
SELECT * FROM mytable WHERE 5 IN (skillid) OR 3 IN (skillid);
SELECT * FROM mytable WHERE skillid LIKE '3%' OR skillid LIKE '5%';
Definetly this is NOT the way to do it...
YOU SHOULD NORMALIZE your table to avoid this kind of problems
This is not good practice, you should normalize your table table, but REGEXP would be helpful
Please try this way
SELECT * FROM mytable WHERE
skillid REGEXP '[[:<:]]3[[:>:]]' OR skillid REGEXP '[[:<:]]5[[:>:]]'

Mysql intersect two strings

I have the following tables:
TableFinal
column id, with first row having value 1
column numbers, with first row having value `1,5,6,33,2,12,3,4,9,13,26,41,59,61,10,7,28`
And
TablePick
column id, with first row having value 1
column numbers, with first row having value 2,12,26,33
I want to check if the numbers from TablePick, column "selected" are contained in the column "numbers" of TableFinal.
I have to mention that in TablePick, the numbers in column "selected" are ordered ASC, while in TableFinal, the numbers in column "numbers" are shuffled.
Usually I would put each of these in an array using PHP and then intersect the 2 arrays and count the resulted array. But in MYSQL, it is not that simple, so practically I have no idea where to start.
Maybe I should create an ARRAY_INTERSECT function? Or do we have a simpler solution?
SELECT * FROM TablePick p RIGHT JOIN TableFinal f ON f.id=p.id WHERE ARRAY_INTERSECT(p.selected,f.numbers)
Sorry to say so, but your schema needs some serious maintenance: NEVER EVER store more than one information in one field, if you need to access them separately.
You need a pair of join tables, where instead of the first row (1, "1,5,6,33,2,12,3,4,9,13,26,41,59,61,10,7,28") you have the rows
(1,1)
(1,5)
(1,6)
(1,33)
...
and instead of the row (1, "2,12,26,33") you have the rows
(1,2)
(1,12)
(1,26)
(1,33)
Now you query is simply:
SELECT ... FROM TableFinal
INNER JOIN TABLE TablePick ON TableFinal.number=TablePick.number
WHERE TableFinal.id=1
AND TablePick.id=1
EDIT
Please understand, that even if this were possible without MySQL abuse, it would be a performance killer, once the number of rows start to rise: We are talking of n*m array intersects, if the tables have n and m rows respectivly.

Categories