Cross table with multiselect - ms-access

I have a table with 2 Columns, filled with strings
CREATE TABLE [tbl_text]
(
[directoryName] nvarchar(200),
[text1] nvarchar(200),
[text2] nvarchar(200)
)
The Strings are build like the following
| Text1 | Text2 |
|------------|----------|
|tz1 tz3 tz2 | al1 al2 |
| tz1 tz3 | al1 al3 |
| tz2 | al3 |
| tz3 tz2 | al1 al2 |
Now i want to Count how many times the TestN or TextN are resulting in the
| Text1 | al1 | al2 | al3 |
|-------|------|------|------|
| tz1 | 2 | 1 | 1 |
| tz2 | 2 | 2 | 1 |
| tz3 | 3 | 2 | 1 |
i tried solving it with an sql-query like this:
TRANSFORM Count(tt.directoryName) AS Value
SELECT tt.Text1
FROM tbl_text as tt
GROUP BY tt.Text1
PIVOT tt.Text2;
This works fine if i got fields only with one value like the third column (the complete datasource has to be like a one-value-style)
But in my case i'm using the strings for a multiselect...
If i try to conform this query onto a datasource filled with the " " between the values the result is complete messed up
Any suggestions how the query should look like to get this result ?

You'll have to split the strings inside Text1/Text2 before you can do anything with them. In VBA, you'd loop a recordset, use the Split() function and insert the results into a temp table.
In Sql Server there are more powerful options available.
Coming from here: Split function equivalent in T-SQL? ,
you should read this page:
http://www.sommarskog.se/arrays-in-sql-2005.html#tablelists

Related

MySQL JSON wildcards

I'm trying to obtain all IDs from table A of the elements which are in a JSON array in table B. My problem is that I don't know how to use wildcard symbols with JSON.
Table A looks like this
+-----------------------+--------------------+
| Identifier (TINYTEXT) | Filter (JSON) |
+-----------------------+--------------------+
| Obj1 | ['Test1', 'Test2'] |
| Obj2 | ['Test3', 'Test4'] |
+-----------------------+--------------------+
and table B looks like this
+-----------+--------------------+
| UID (INT) | Object (TINYTEXT) |
+-----------+--------------------+
| 1 | xyzTest1, abc |
| 2 | xyzTest2, abc |
| 3 | xyzTest3, abc |
| 4 | xyzTest4, abc |
+----------------+---------------+
I want to use A.Identifier as the input to get B.UID as the output, applying the filter A.Filter on B.Object using wildcard symbols.
Example:
I have A.Identifier = 'Obj1' and want to find all B.UID for the corresponding B.Object that contain Test1 or Test2 (A.Filter). In this case, the output would be 1 and 2.
The SQL code without the inner join I would manually use for this is
SELECT UID FROM B WHERE Object LIKE '%Test1%' OR Object LIKE '%Test2%';

Separating a comma separated string to a new table

I inherited a project that has comma separated strings stored in a field called 'subsector' in a table named 'com_barchan_project'. I need to change this horrible design, since it's proving to be an issue trying to parse through this field. See HERE for the full story:
| id | name | sector | subsector |
+----+------+--------+-----------+
| 1 | test | 2 | 3,4,7 |
+----+------+--------+-----------+
| 2 | door | 5 | 2 |
I have created a new table called 'com_barchan_project_subsector_join' with the required fields and would like to move the values stored in 'com_barchan_project' to this new empty table.
Can anyone help me with the SQL statement that would accomplish this?
Here's what the new 'com_barchan_project_subsector_join' table should look like:
| id | project_id | subsector_id |
+----+------------+--------------+
| 1 | 1 | 3 |
+----+------------+--------------+
| 2 | 1 | 4 |
+----+------------+--------------+
| 3 | 1 | 7 |
+----+------------+--------------+
| 4 | 2 | 2 |
Once I move over the data, I will remove the 'subsector' field from the 'com_barchan_project' table and be done with it.
Thanks for your help!!!
John
Using shorter table names for brevity/clarity; and assuming you have (or can easily make) a comprehensive subsectors table...and assuming your csv are stored in a consistent format (no spaces at least).
INSERT INTO `project_subsectors` (project_id, subsector_id)
SELECT p.id, s.id
FROM projects AS p
INNER JOIN subsectors AS s ON p.subsector = s.id
OR p.subsector LIKE CONCAT(s.id, ',%')
OR p.subsector LIKE CONCAT('%,', s.id, ',%')
OR p.subsector LIKE CONCAT('%,', s.id)
;
I can't guarantee it will be fast; I'd be surprised if it was.
ON FIND_IN_SET(s.id, p.subsector) > 0 may work as well, but I am not as familiar with the behavior of that function.

MS Access Update on specific SQL select same table

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.

MySQL In result are NULL's when join left 3 tables

I have problem with result when join 3 tables because I have in some place NULL a should be number or empty cell.
My tables in database:
Table nr 1: rysunek
id_rys | nazwa_rys | nazwa_klienta | ...
3 |01_116230_C0 |PHILIPS
7 |11_002177_A0 |P&G
20 |01_101854_B0 |MARS FOOD
333 |None |None
( + 7 columns which do not use in this query)
Table nr 2: artykul
id_art |id_rys |nazwa_art | id_status | ...
1 |3 |00_16_1234 | 1
2 |7 |00_16_1235 | 3
3 |7 |00_16_1236 | 0
4 |333 |00_16_1237 | 0
( + 10 columns which do not use in this query)
Table nr 3: statusy
id_status |kod_status
1 |IA
2 |NC
3 |861
Mysql query looks like this:
SELECT r.nazwa_klienta
, r.nazwa_rys
, a.nazwa_art
, s.kod_status
FROM artykul a
LEFT
JOIN rysunek r
ON a.id_rys = r.id_rys
LEFT
JOIN statusy s
ON a.id_status = s.id_status;
And result looks like this:
nazwa_klienta | nazwa_rys | nazwa_art | kod_status
NULL | NULL | 00_16_1234 | IA
NULL | NULL | 00_16_1235 | 861
P&G | 11_002177_A0 | 00_16_1236 | NULL
None | None | 00_16_1237 | NULL
I need to the result of query above look like this:
nazwa_klienta | nazwa_rys | nazwa_art | kod_status
PHILIPS | 01_116230_C0 | 00_16_1234 | IA
P&G | 11_002177_A0 | 00_16_1235 | 861
P&G | 11_002177_A0 | 00_16_1236 | [empty cell]
None | None | 00_16_1237 | [empty cell]
How should looks like my query? I tried all join methods but none of them work.
Maybe I should change structure of my tables? I'm waiting for some suggestion from somebody... :)
Left joins are going to create empty entries for your rysunek columns whenever there is no row in that table that matches artykul's. If you don't want them listed, then don't use an outer join between those two tables (I note you didn't list them in your desired output).
For the other NULLs, from kod_status, since it is a numeric column, pretty much your choices are: take the null; or turn it into a 0 with a COALESCE(kod_status,0), or cast the result to a string and turn its nulls into empty strings. There are command-line options in the mysql command-line tool (which your output appears to be from) (see http://dev.mysql.com/doc/refman/5.7/en/mysql-commands.html ) there may be a way to change how it outputs nulls if that would fit your use-model needs.

Group by ID, separate the rest into different columns

I'm trying to create a table that looks like the following examples..
| SO_NUMBER | ORDER |
------------------------------------------
| 12345 | iphone5|1|500|APPLE |
| 12345 | icase-blk|1|20|CaseCompany |
| 23411 | galaxy5|1|500|Samsung |
| 23411 | galaxy-blk|1|20|CaseCompany|
Convert that to this..
| SO_NUMBER | ORDER_1 | ORDER_2
-----------------------------------------------------------------------
| 12345 | iphone5|1|500|APPLE | icase-blk|1|20|CaseCompany
| 23411 | galaxy5|1|500|Samsung | galaxy-blk|1|20|CaseCompany
I'm not sure where to start, I can group by the SO_Number fine, but not sure if I need to create a temporary table. I've search around and all I could find is grouping them together with commas but that won't work for this.
EDIT:
I've started looking at Option Compare Database RunningCount Script to do what i asked for. It works for the most part.
Option Compare Database
Option Explicit
Public wName As String
Public wRuningCount As Long
Function GetRunCount(Name1) As Long
If wName = Name1 Then
wRuningCount = wRuningCount + 1
Else
wName = Name1
wRuningCount = 1
End If
GetRunCount = wRuningCount
End Function
But now I get
| SO_NUMBER | ORDER_1 | ORDER_3 |
instead of
| SO_NUMBER | ORDER_1 | ORDER_2 |
The query the auto script setup is the following..
TRANSFORM First([123].ORDER) AS FirstOfORDER
SELECT [123].SO_NUMBER
FROM 123
GROUP BY [123].SO_NUMBER
PIVOT [123].GetRunCount;
Use the Query Wizard and create a crosstab query. Below is a sample:
TRANSFORM First([Tbl1].[SO_NUMBER]) AS FirstOftype
SELECT [Tbl1].[SO_NUMBER]
FROM Tbl1
GROUP BY [Tbl1].[SO_NUMBER]
PIVOT [Tbl1].[Order];