Count of unique characteristics in duplicate rows table - google-apps-script

My table is having duplicate rows listed based on a duplicates ID column. The duplicate rows may have one or more Characteristic columns having unique values. I am trying to get a count of which Characteristic columns in duplicate rows have unique values.
Before:
+-----+----------+-------------+-----------+------------+
| ID | charType | charFlavour | charColor | charWeight |
+-----+----------+-------------+-----------+------------+
| 123 | gel | mint | blue | 10gms |
| 123 | liquid | mint | blue | 10gms |
| 123 | solid | mint | blue | 10gms |
| 456 | wood | orange | red | 20gms |
| 456 | wood | vanilla | red | 20gms |
| 456 | wood | raspberry | red | 20gms |
| 456 | wood | strawberry | red | 20gms |
| 789 | metal | mango | yellow | 25gms |
| 789 | metal | mango | yellow | 30gms |
| 789 | metal | mango | yellow | 22gms |
| 333 | silica | NA | magenta | 11gms |
| 333 | plastic | NA | white | 11gms |
| 333 | rubber | NA | teal | 11gms |
+-----+----------+-------------+-----------+------------+
After:
+-------------+-----+-----+-----+-----+-------+
| ID | 123 | 456 | 789 | 333 | Total |
+-------------+-----+-----+-----+-----+-------+
| charType | 1 | 0 | 0 | 1 | 2 |
| charFlavour | 0 | 1 | 0 | 0 | 1 |
| charColor | 0 | 0 | 0 | 1 | 1 |
| charWeight | 0 | 0 | 1 | 0 | 1 |
+-------------+-----+-----+-----+-----+-------+
Is this format possible using a Pivot-table or Google Query?

Perhaps this isn't the most elegant solution you were looking for — it appears that no function in Google's query language returns all the unique values of a column. But this solution should successfully count, for each attribute, how many IDs correspond to more than one value of that attribute. For example, it will count how many IDs correspond to multiple charFlavours. Here are the two steps/queries to make:
=QUERY(A1:E, "select A, max(B), min(B), max(C), min(C), max(D), min(D), max(E), min(E) group by A", 1): This will select the alphabetically/numerically maximum and minimum value for each attribute with respect to each ID. It will return one row per ID, containing the min and max attribute values.
For each attribute, use something like =QUERY(G1:O, "select count(G) where H != I", 1). If you have four attributes, you will need four of these calls; just change where H != I to be the two columns corresponding to each attribute. Each of these QUERY calls will generate a table with just one value, the number of IDs having multiple values for a certain attribute.

Related

Update one column based on matching values of two columns from the same table

Basically I have 3 columns, like this:
+-------------+-------------+--------+
| startpoint | endpoint | number |
+-------------+-------------+--------+
| 15037232632 | 4226861620 | null |
| 4226862003 | 4226862079 | null |
| 4226862079 | 4226862111 | null |
| 4226862111 | 4226862121 | 2 |
| 4226862121 | ---------- | 1 |
| 15025374738 | 4226862003 | null |
| 4226861620 | 15025374738 | null |
| 4226801794 | 15037232632 | null |
+-------------+-------------+--------+
What I am trying to do is:
Step 1 : I assign a number '1' to any one of the IDs from the 'startpoint' column
Step 2 : Match the 'startpoint' ID to which I assigned the number in the previous step with the IDs in the 'endpoint' column
Step 3 : After the 'startpoint' ID matches with the 'endpoint' ID, I assign the number 2 in the 'number' column on the ROW where the endpoint matched
Step 4: On the row where number was assigned, I take the 'startpoint' ID and then repeat the steps 2-4 again.
I have tried playing around with the update query but it doesn't seem right. Any help would be appreciated.
EDIT:
I am also including the expected output. The table without applying any queries is given above
+-------------+-------------+--------+
| startpoint | endpoint | number |
+-------------+-------------+--------+
| 15037232632 | 4226861620 | 7 |
| 4226862003 | 4226862079 | 4 |
| 4226862079 | 4226862111 | 3 |
| 4226862111 | 4226862121 | 2 |
| 4226862121 | ---------- | 1 |
| 15025374738 | 4226862003 | 5 |
| 4226861620 | 15025374738 | 6 |
| 4226801794 | 15037232632 | 8 |
+-------------+-------------+--------+

MS Access Report Field Value as Heading with Other Field Values Beneath in Table

In a Microsoft Access report, how can I display each record of a field as a column heading with the records of other fields in that columns records beneath it.
My query gives me data in the following format:
| ID | Item | Item Characteristic 1 | Item Characteristic 2 | Other Fields |
|:--:|:------:|:---------------------:|:---------------------:|--------------|
| 22 | Code 1 | Blue | 48 | … |
| 22 | Code 2 | Red | 50 | … |
| 22 | Code 3 | Green | 99 | … |
I'd like to have on my report to look something like this:
| Heading | Data True to All Records1 | More Data True to All Records2 | |
|:---------------------:|:-------------------------:|:------------------------------:|:------------:|
| ------------ | ------------ | ------------ | ------------ |
| Item | Code 1 | Code 2 | Code 3 |
| Item Characteristic 1 | Blue | Red | Green |
| Item Characteristic 2 | 48 | 50 | 99 |
| Other Fields | … | … | … |
| ------------ | ------------ | ------------ | ------------ |
| Footer | Data True to All Records3 | More Data True to All Records4 | |
Currently, I can only get data in the format:
| Heading | | |
|:-------:|:-----:|:--:|
| ---- | | |
| Code 1 | Blue | 48 |
| | | |
| Code 2 | Red | 50 |
| | | |
| Code 3 | Green | 99 |
| --- | | |
| Footer | | |
Where each record is resulting in a new 'row' in the report.
Can anyone help?
Table needs a unique record identifier - an autonumber type field should serve, then consider the following.
Query1:
SELECT RecID, ID, "Item" AS Category, Item AS Data FROM Tablename
UNION SELECT RecID, ID, "ItemChar1", ItemChar1 FROM Tablename
UNION SELECT RecID, ID, "ItemChar2", ItemChar2 FROM Tablename;
Query2:
TRANSFORM First(Query1.Data) AS FirstOfData
SELECT Query1.ID, Query1.Category
FROM Query1
GROUP BY Query1.ID, Query1.Category
PIVOT Query1.RecID;
For posterity, I resolved this by setting out a table of unbound labels.
I gave each of these labels a control name of x-y, where x was the column number and y was the row number.
I then looped through each column and row and changed the caption of the label to the value from my RecordSet.
(Form("FormName").Controls.Item(x & "-" & y)).Caption = .Fields("FieldName")

Compare different rows and bring out result

I have a table which requires me to pair certain rows together using a unique value that both the rows share.
For instance in the below table;
+--------+----------+-----------+-----------+----------------+-------------+
| id | type | member | code | description | matching |
+--------+----------+-----------+-----------+----------------+-------------+
| 1000 |transfer | 552123 | SC120314 | From Gold | |
| 1001 |transfer | 552123 | SC120314 | To Platinum | |
| 1002 |transfer | 833612 | SC120314 | From silver | |
| 1003 |transfer | 833612 | SC120314 | To basic | |
| 1004 |transfer | 457114 | SC150314 | From Platinum | |
| 1005 |transfer | 457114 | SC150314 | To silver | |
| 1006 |transfer | 933276 | SC180314 | From Gold | |
| 1007 |transfer | 933276 | SC180314 | From To basic | |
+--------+----------+-----------+-----------+----------------+-------------+
basically What i need the query / routine to do is find the rows where the value in the 'member' column for each row match. Then see if the values in the 'code' column for the same found rows also match.
If both columns for both rows match, then assign a value to the 'matching' column for both rows. This value should be the same for both rows and unique to only them.
The unique code can be absolutely anything, so long as it's exclusive to matching rows. Is there any query / routine capable of carrying this out?
I'm not sure I understand the question correctly, but if you like to pick out and update rows where the code and member columns matches and set matching to some unique value for each of the related rows, I believe this would work:
UPDATE <table> A
INNER JOIN (SELECT * FROM <table>) B ON
B.member = A.member && B.code = A.code && A.id <> B.id
SET A.matching = (A.id + B.id);
The matching value will be set to the sum of the id columns for both rows. Notice that updating the matching field this way will not work if there are more than two rows that can match.
Running the above query against your example table would yield:
+------+----------+--------+----------+---------------+----------+
| id | type | member | code | description | matching |
+------+----------+--------+----------+---------------+----------+
| 1000 | transfer | 552123 | SC120314 | From Gold | 2001 |
| 1001 | transfer | 552123 | SC120314 | To Platinum | 2001 |
| 1002 | transfer | 833612 | SC120314 | From Silver | 2005 |
| 1003 | transfer | 833612 | SC120314 | To basic | 2005 |
| 1004 | transfer | 457114 | SC150314 | From Platinum | 2009 |
| 1005 | transfer | 457114 | SC150314 | To silver | 2009 |
| 1006 | transfer | 933276 | SC180314 | From Gold | 2013 |
| 1007 | transfer | 933276 | SC180314 | From To basic | 2013 |
+------+----------+--------+----------+---------------+----------+
I can give you a simple query what can do what you need.
tst is the name of the table.
SELECT *, COUNT( t2.id ) as matching FROM tst t LEFT JOIN tst t2 ON t2.member = t.member GROUP BY t.id

Subtract values from line above the current line in MySQL

I've the following table:
| id | Name | Date of Birth | Date of Death | Result |
| 1 | John | 3546565 | 3548987 | |
| 2 | Mary | 5233654 | 5265458 | |
| 3 | Lewis| 6546876 | 6548752 | |
| 4 | Mark | 6546546 | 6767767 | |
| 5 | Steve| 6546877 | 6548798 | |
And I need to do this for the whole table:
Result = 1, if( current_row(Date of Birth) - row_above_current_row(Date of Death))>X else 0
To make things easier, I guess, I created the same table above but with 2 extra id fields: id_minus_one and id_plus_one
Like this:
| id | id_minus_one | id_plus_one |Name | Date_of_Birth | Date_of_Death | Result |
| 1 | 0 | 2 |John | 3546565 | 3548987 | |
| 2 | 1 | 3 |Mary | 5233654 | 5265458 | |
| 3 | 2 | 4 |Lewis| 6546876 | 6548752 | |
| 4 | 3 | 5 |Mark | 6546546 | 6767767 | |
| 5 | 4 | 6 |Steve| 6546877 | 6548798 | |
So my approach would be something like (in pseudo code):
for id=1, ignore result. (Because there is no row above)
for id=2, Result = 1 if( (Where id=2).Date_of_Birth - (where id_minus_one=id-1).Date_of_Death )>X else 0
for id=3, Result = 1 if( (Where id=3).Date_of_Birth - (where id_minus_one=id-1).Date_of_Death)>X else 0
and so on for the whole table...
Just ignore id_plus_one if there is no need for it, I'll use it later for the same thing. So, if I manage to do this for id_minus_one I'll manage for id_plus_one as they are the same algorithm.
My question is how to pass that pseudo code into SQL code, I can't find a way to relate both ids in just one select.
Thank you!
As you describe this, it is just a self join with some logic on the select:
select t.*,
((t.date_of_birth - tprev.date_of_death) > x) as flag
from t left outer join
t tprev
on t.id_minus_one = tprev.id

MySQL - Use Header Name as Part of Query Filter

I'm relatively new to MySQL and have come across a problem to which I cannot seem to find a solution. I have searched but could not find an answer. I'm open to the possibility that I'm not asking the question correctly. Here goes:
I'm trying to use the name of a given column and the values within that column from one table to pull values from another table. The first table contains 3 columns with the response codified. The second table contains the definitions for each code for each item. The same number code is associated with different meanings depending on the item. For example:
table1 (this table cannot change):
--------------------------------------------------------------
|result_id | f_initial | l_name | item_A | item_B | item_C |
--------------------------------------------------------------
| 1 | j | doe | 1 | 3 | 2 |
| 2 | k | smith | 3 | 1 | 2 |
| 3 | l | williams | 2 | 2 | 1 |
--------------------------------------------------------------
table2 (this table can be modified, split, or whatever needs to be done):
-------------------------------------------
|item_id | item_name | score | definition |
-------------------------------------------
| 1 | item_A | 1 | agree |
| 2 | item_A | 2 | neutral |
| 3 | item_A | 3 | disagree |
| 4 | item_B | 1 | likely |
| 5 | item_B | 2 | not likely |
| 6 | item_B | 3 | no reply |
| 7 | item_C | 1 | yes |
| 8 | item_C | 2 | no |
-------------------------------------------
My goal is for the query to output the following:
--------------------------------------------------------------------
|result_id | f_initial | l_name | item_A | item_B | item_C |
--------------------------------------------------------------------
| 1 | j | doe | agree | no reply | no |
| 2 | k | smith | disagree | likely | no |
| 3 | l | williams | neutral | not likely | yes |
--------------------------------------------------------------------
Any assistance or guidance is greatly appreciated. Thank you in advance.
You must join the two tables on the item_A/B/C and score columns
select t1.result_id, t1.f_initial, t1.l_name,
t2a.definition as item_a,
t2b.definition as item_b,
t2c.definition as item_c
from table1 t1
join table2 t2a on t2a.score = t1.item_a
join table2 t2b on t2b.score = t1.item_b
join table2 t2c on t2c.score = t1.item_c
where t2a.item_name = 'item_A'
and t2b.item_name = 'item_B'
and t2c.item_name = 'item_C'