I've written a query on a table which contains a list of 'Statements' against 'Companies' like so (obviously simplified):
Statement | Company
---------------------------
ABC | CompA
ABC | CompB
DEF | CompC
The query presents the information like so:
Statement | CompA | CompB | Comp C
--------------------------------------
ABC | X | X |
DEF | | | X
Using the code like this:
SELECT
[Requirement_Text],
CASE WHEN(SUM(CASE WHEN Company = 'CompA' THEN 1 END)) IS NOT NULL THEN 'X' ELSE ' ' END AS CompA,
CASE WHEN(SUM(CASE WHEN Company = 'CompB' THEN 1 END)) IS NOT NULL THEN 'X' ELSE ' ' END AS CompB,
CASE WHEN(SUM(CASE WHEN Company = 'CompC' THEN 1 END)) IS NOT NULL THEN 'X' ELSE ' ' END AS CompC,
CASE WHEN(SUM(CASE WHEN Company IS NULL THEN 1 END)) IS NOT NULL THEN 'X' ELSE ' ' END AS NILL
FROM [StatementTable]
Now, this is easy enough because we have a finite number of companies, but if we were to say move it down to Department level (instead of Company) then we have several more (an unknown number - N).
So the question is, how can I create the columns in the output table based on the number of distinct values in a given column of the input table?
For example:
Statement | Company | Department
---------------------------------------
ABC | CompA | Dept(1)
DEF | CompA | Dept(2)
DEF | CompA | Dept(3)
GHI | CompA | Dept(3)
ABC | CompB | Dept(N-1)
DEF | CompC | Dept(N)
Will become:
Statement | Dept(1) | Dept(2) | Dept(3) | Dept(N-1) | Dept(N)
---------------------------------------------------------------
ABC | X | | | X |
DEF | | X | X | | X
GHI | | | X | |
NOTE: In this case I've disregarded the company name.
Thanks in advance.
you should use Dynamic query and Pivote :
Check This out
and you can see the document here :
Check this
Related
I have sample Data
+----+-----------+
| Id | Name |
+----+-----------+
| 1 | $John |
| 2 | $Carol |
| 3 | $Mike |
| 4 | $Sam |
| 5 | $David$Mohan$ |
6 | $David$
7 | $David$Mohan$
| 8 | Robert$Ram$ |
| 9 | Maxwell$ |
+----+-----------+
I need to remove the only $ first character
Need output :
+----+-----------+
| Id | Name |
+----+-----------+
| 1 | John |
| 2 | Carol |
| 3 | Mike |
| 4 | Sam |
| 5 | David$Mohan |
6 | David
7 | David$Mohan
| 8 | Robert$Ram |
| 9 | Maxwell |
+----+-----------+
Select REPLACE(col,'$','') from Tbl
select regexp_replace(name, '^$', '') name from mytable
I have tried with Replace and Substring but still missing the point .
Can anyone suggest me .
If you are only looking for starting $, you can use this below logic-
DEMO HERE
SELECT
CASE
WHEN LEFT(D,1) = '$' THEN RIGHT(D, LENGTH(D)-1)
ELSE D
END STR,
IF(LEFT(D,1) = '$', RIGHT(D, LENGTH(D)-1), D) STR2
-- you can use any of the above option
FROM
(
select '$David$Mohan$' D UNION ALL
select 'Da$Mo$'
)A
Try this:
select
id,
case when SUBSTR(Name, 1,1)='$' and SUBSTR(Name,-1,1)='$' then substr(Name,2,(length(Name)-2))
when SUBSTR(Name, 1,1)='$' then substr(Name,2)
else Name
end
from Tbl
Based on your example you should try;
Replace(trim(replace({col},'$',' ')), ' ','$')
This is turning the '$' into spaces, removing spaces at the start or end or the string, then switching back to '$'.
Try this, it's working for me for all your test cases
SELECT REGEXP_SUBSTR(name,'[^$].+[^$]') from users;
If case you want to replace $ with space, David$Ang => David Ang
SELECT REGEXP_REPLACE(REGEXP_SUBSTR(name,'[^$].+[^$]'), "[$]", " ") from users;
I have this table
| BookID | BookTitle | NumberOfPages | NoOfCopies |
+--------+--------------------------------+---------------+------------+
| 1 | The Help | 444 | 4 |
| 2 | The Catcher in the Rye | 277 | 10 |
| 3 | Crime and Punishment | 545 | 2 |
| 4 | The Brothers Karamazov | 795 | 1 |
| 5 | A Crown of Wishes | 369 | 12 |
| 6 | The Fireman | 752 | 3 |
| 7 | Fahrenheit 451 | 174 | 9 |
| 8 | The Hobbit | 366 | 1 |
| 9 | Lord of Emperors | 560 | 4 |
| 10 | Holy Bible: King James Version | 1590 | 11 |
----------------------------------------------------------------------------
When I insert a book title and expect it to return the book id, it always returns an empty set
so far, I have tried these queries.->book_info is the name of the table:
select BookID from book_info where ucase(BookTitle) = ' THE HELP% ';
select BookID from book_info where BookTitle = ' The Help ';
select BookID from book_info where lcase(trim(BookTitle) = 'the help';
but none of them worked.
Note I don't rely on sql in my job.
you need to use like if you want to use "%"
when you use "=" you need to sure it is same. even space also count
select BookID from book_info where BookTitle LIKE 'THE HELP%';
The issue here is with the operator you are using and the value you are function you are expecting from it, = operator checks for the exact match that's why your queries are returning no records:
select BookID from book_info where ucase(BookTitle) = ' THE HELP% ';
select BookID from book_info where BookTitle = ' The Help ';
select BookID from book_info where lcase(trim(BookTitle) = 'the help';
And one more thing that is:
MySQL queries are not case-sensitive by default.
So you don't need to add the string methods here to change the values case.
We usually use the % with LIKE only like this:
select BookID from book_info where ucase(BookTitle) LIKE '%THE HELP%';
In this query LIKE %THE HELP% will match all the string having THE HELP in them;
I'm currently trying to update an existing database (removing duplicates).
You can see the structure as follows :
I have a database on which specific entries are marked as "Main". These entries need to be updated with data from duplicate records, only having the same name.
(Updated table to reflect my question better)
It would look like this:
+----+------+-----------------+--------------+---------+
| ID | Name | Field-To-Update | Duplication | Source |
+----+------+-----------------+--------------+---------+
| . | A | xxx | Main | 1 |
| . | A | yyy | "" | 2 |
| . | A | zzz | "" | 3 |
| . | B | foo | "" | 1 |
| . | B | bar | Main | 2 |
+----+------+-----------------+--------------+---------+
Should result in
+----+------+-----------------+--------------+-----------------------------------------------+
| ID | Name | Field-To-Update | Duplication | Source |
+----+------+-----------------+--------------+-----------------------------------------------+
| . | A | yyy | Main | 1 |
| . | A | yyy | "" | 2 |
| . | A | zzz | "" | 3 (should be updated from a specific source) |
| . | B | bar | "" | 1 |
| . | B | bar | Main | 2 (should be updated from a specific source) |
+----+------+-----------------+--------------+-----------------------------------------------+
Do any of you have an idea how to tackle this? I've tried with multiple queries for a couple of days now without any success.
you could use a update with join
update t
set t.field_to_update = x.field_to_update
from your_table t
inner join ( select name, field_to_update
from your_table
where Duplication <> 'Main') x
) on t.name = x.name
where t.Duplication = 'Main'
Bizarre requirement. You say you are updating to remove duplicates, however, it looks to me like you are creating duplicates.
There are only 2 records for each Name? Try:
UPDATE Table INNER JOIN
(SELECT Name, [Field-To-Update]
FROM Table
WHERE Duplication Is Null) AS Query1 ON
Table.Name = Query1.Name SET Table.[Field-To-Update] = [Query1]![Field-To-Update] WHERE Duplication = "Main";
Name is a reserved word in Access. Should not use reserved words as name for anything.
Darn! Did not see #scaisEdge answer before posting.
I tried the <> "Main" criteria and it did not work which was surprising - no records returned. So I switched to the Is Null parameter.
If you want to pull value from the maximum Source for each Name, then need a query that does that. Review http://allenbrowne.com/subquery-01.html#TopN. Then use that query in the above example as Query1.
I've got a permission/privileges - table looking like this:
+----+----------+----------+------+-------+
| id | name | usertype | read | write |
+----+----------+----------+------+-------+
| 1 | test | A | 0 | 0 |
| 2 | test | MU | 1 | 1 |
| 3 | test | U | 1 | 1 |
| 4 | apple | A | 1 | 1 |
| 5 | apple | MU | 1 | 0 |
| 6 | apple | U | 0 | 0 |
| 7 | flower | A | 0 | 0 |
| 8 | flower | MU | 0 | 0 |
| 9 | flower | U | 1 | 1 |
+----+----------+----------+------+-------+
there are 3 usertypes: A (admin), MU (maintenance user), U (standard user)
the usertypes are hierarchical: A > MU > U
(the usertypes are saved as CHAR(2) in the database, and unfortunately I can't change that)
now i want to build a query which implements the hierarchical logic of my usertypes.
e.g. usertype 'A' got no permission to read or write on stuff with the name 'test', thus usertypes 'MU' AND 'U' also should have no permission for that and their read = 1 and write = 1 should be ignored.
I know which usertype is currently logged in.
I somehow have to check for the minimum of read/write rights to the name for all hierarchical predecessors, i guess. but i don't know how to check that since usertype is not a number field.
this is what I've tried so far:
SELECT
name,
MIN(read),
MIN(write),
CASE
WHEN usertype = 'A' THEN 0
ELSE (CASE
WHEN usertype = 'WU' THEN 1
ELSE 2
END)
END userval
FROM
permissions
-- WHERE usertype <= :current_usertype
GROUP BY name
this seems to work, but i don't know how i can get my condition WHERE usertype <= :current_usertype working, so a usertype down in the hierarchy can't get more privileges on a name than a "higher" usertype.
any ideas?
thanks in advance!
This is how I solved my problem:
1. I added another table "permission_groups" to the database:
+----+----------+--------+
| id | usertype | value |
+----+----------+--------+
| 1 | A | 100 |
| 2 | MU | 20 |
| 3 | U | 10 |
+----+----------+--------+
2. Then I joined this table to my original table "permissions" which i showed in my question:
here i get the value of my "permission_groups" table with a subquery. this value symbolizes the hierarchical order of my different usertypes.
SELECT
perm.name,
MIN(perm.`read`),
MIN(perm.`write`),
group .value
FROM
permissions perm
LEFT JOIN permission_groups group ON group.usertype = perm.usertype
WHERE
group.value >= (SELECT value from permission_groups WHERE usertype = :current_usertype)
GROUP BY perm.name
:current_usertype is a PDO parameter in my case, which is replaced by the usertype of the current user.
Table A
| SLNO | TYPENAME | TYPEMODE |
------------------------------
| 1 | Act.Alw | A |
| 2 | Canteen | D |
I want to display two column according to its typmode
using UNION ALL I get
| Addition | Deduction |
------------------------
| Act.Alw | |
| | Canteen |
I want display like this. Addtion and Deduction are alias
| ADDITION | DEDUCTION |
------------------------
| Act.Alw | Canteen |
It looks like you need to use a join instead of a union. But it would be helpful if you could explain a little bit more about what you are trying to accomplish and maybe post he sql query you are currently trying to run.
You can use CASE statement for that. To group them you need to use GROUP_CONCAT function like this:
SELECT GROUP_CONCAT(CASE WHEN typemode = 'A'
THEN typename ELSE NULL END) AS Addition
,GROUP_CONCAT(CASE WHEN typemode = 'D'
THEN typename ELSE NULL END) AS Deduction
FROM Table1
Output:
| ADDITION | DEDUCTION |
------------------------
| Act.Alw | Canteen |
See this SQLFiddle