How to join values in one cell based on multiple conditions? - concatenation

My question is very similar to How to concatenate values in multiple cells based on a condition? and I've had a lot of success applying Mourits de Beer's answer in the past; however for my current problem, I need to only join values that meet two sets of criteria instead of one.
I have Sheet_1 with ID numbers, PO numbers, and Text values that looks like this:
ID
PO
CLASS
1
223
A
1
334
B
2
334
A
3
556
B
3
445
A
1
445
A
3
334
B
I have a Sheet_2 with unique IDs where I need to join all unique PO numbers into a single cell based on whether they are Class A or B, like this:
| ID | CLASS = A and ID = A2 | CLASS = B and ID = A2 |
| ----- |---------------------- | ---------------------- |
| 1 | 223, 445 | 334 |
| 2 | 334 | N/A |
| 3 | 445 | 556, 334 |
I tried to nest an AND() function inside of the IF function so the formula only works if BOTH conditions are met, but this isn't returning all true values.
=ARRAYFORMULA(TEXTJOIN(", ",TRUE,(UNIQUE(IF(AND(Sheet_1!$ID$2:$ID=$Sheet_2!ID2,'Sheet_1!$CLASS$2:$CLASS="A"),Sheet_1!$PO$2:$PO,"NA")))))
I need the function to work in Excel/Google Sheets and do not have strong VBA skills, but any help is appreciated! (This is also my first question here, so please be kind and let me know if there is anything I can do to explain/post my questions better next time. Thank you!)

Related

Find max of multiple columns (row-wise) and columns' names where max. values occurred (T-SQL)

I am fairly new to T-SQL and advanced concepts/queries and I have difficulty trying to figure out the situation described further. Lets say, I have a table like this:
--------------------
| K | C1 | C2 | C3 |
--------------------
| 1 | 14 | 24 | 48 |
| 2 | 10 | 65 | 37 |
| 3 | 44 | 90 | 22 |
--------------------
I need to find maximums row-wise, which has already been asked many times on SO, AND what makes difference, in addition, I also want the columns' names where found maximums occurred. The result has to be like this:
-- how to get Col column?
-----------------
| K | Max | Col |
| 1 | 48 | C3 |
| 2 | 65 | C2 |
| 3 | 90 | C2 |
-----------------
I learned how to find maximum rows-wise based on this and this threads, but I cannot understand how I could add another column containing columns' names where max. values occurred. I know I kinda have to show efforts but actually I cannot show anything since I just don't quite understand how to do it and all my attempts just return errors. Any ideas, hints? Thanks in advance!
The simplest way in SQL Server is to use apply:
select t.k, v.col, v.val
from t cross apply
(select top 1 v.col, v.val
from (values ('C1', t.C1), ('C2', t.C2), ('C3', t.C3)
) v(col, val)
order by val desc
) v(col, val)
I would approach this problem by joining a temporary maximum table back to the original and then writing a long "case when", assuming you have a reasonable number of columns. It would look like the following.
Select a.K
, b.Max_Value
, Case When a.Column_1 = b.Max_Value Then C1
When a.Column_2 = b.Max_Value Then C2
When a.Column_3 = b.Max_Value Then C3
... As Col
From Your_Table as a Left Join Max_Table as b on a.K = b.K
I believe this should get you what you want if I understood the question correctly. If you have a lot of columns where this would get too long then there's probably a better approach.

Using Data from One Table in Another Table in Access

Hallo StackOverflow Users
I am struggling with transferring values between Access database tables which I will use in a Delphi program to tally election votes and determine the winning candidates. I have a total of six tables. One is my overall table, tblCandidates which identifies each candidate and contains the amount of votes they received from each party, namely the Grade Heads, the Teachers and the Learners. When it comes to the Learners we have four participating grades, namely the grade 8’s, 9’s, 10’s and 11’s, and each grade again has multiple participating classes, namely class A, B, C, etc.
Now, I have set up tables for each grade that contains all the classes in that grade. I named these tables tblGrX with X being the grade represented by 8 through 11. Each one of these tables has two extra fields, namely a field to identify a candidate and a field that will add up all the votes that candidate received from each of the classes in that grade. Lastly I have another table, tblGrTotals with fields Total_GrX (once again with X being the grade), that will contain all the total votes a candidate received from each grade, adding them up in another field for my tblCandidates table to use in its Total_Learners field.
So in short, I want, for example, tblGrTotals to use the value in the field Total of tblGr8 in its Total_Gr8 field, and then tblCandidates to use the value in field Total of tblGrTotals in its Total_Learners field. Is there any way to keep these values updated between tables like cells are updated in Excel the moment a change is made?
Thank you in advance!
You need to rethink your table design. I guess your background is Excel, and your tables are laid out like you would do in Excel sheets, but a relational database works differently.
Think about the objects you are modelling.
Candidates - that's easy. ID, Name, perhaps additional info that belongs to each candidate. But nothing about votes here.
"Groups that are voting" or Parties. Not so trivial, due to the different types of parties. Still I would put them in one table, with Grade and Class only set for Learners, NULL for Heads and Teachers.
e.g.
+----------+------------+-------+-------+
| Party_ID | Party_Type | Grade | Class |
+----------+------------+-------+-------+
| 1 | Head | | |
| 2 | Teacher | | |
| 3 | Learner | 8 | A |
| 4 | Learner | 8 | B |
| 5 | Learner | 8 | C |
| 6 | Learner | 9 | A |
| 7 | Learner | 9 | B |
| 8 | Learner | 10 | A |
+----------+------------+-------+-------+
Votes: they are a Junction Table between Candidates and Parties.
e.g.
+----------+--------------+-----------+
| Party_ID | Candidate_ID | Num_Votes |
+----------+--------------+-----------+
| 1 | 1 | 5 |
| 1 | 2 | 17 |
| 3 | 1 | 2 |
| 3 | 2 | 6 |
| 3 | 3 | 10 |
+----------+--------------+-----------+
Now: if you want to know the votes of Class 8A:
SELECT Candidate_ID, SUM(Num_Votes)
FROM Parties p INNER JOIN Votes v
ON p.Party_ID = v.Party_ID
WHERE p.Party_Type = 'Learner'
AND p.Grade = 8
AND p.Class = 'A'
GROUP BY Candidate_ID
Or of all Grade 8? Simply omit the p.Class criteria.
For the votes per candidate you join Candidates with Votes.
Edit:
for the votes counting differently, this is an attribute of Party_Type.
We don't have a table for them yet, so create one:
+------------+---------------+
| Party_Type | Multiplicator |
+------------+---------------+
| Head | 4 |
| Teacher | 3 |
| Learner | 1 |
+------------+---------------+
and to count all votes:
SELECT c.Candidate_ID, c.Candidate_Name, SUM(v.Num_Votes * t.Multiplicator) AS SumVotes
FROM Parties p
INNER JOIN Votes v ON p.Party_ID = v.Party_ID
INNER JOIN Party_Types t ON p.Party_Type = t.Party_Type
INNER JOIN Candidates c ON v.Candidate_ID = c.Candidate_ID
GROUP BY c.Candidate_ID, c.Candidate_Name
With a design like this, you don't need to keep updating data from one table into another - you calculate it when and how you need it, and it's always current.
The magic of databases. :)

Django QuerySet - Multiple Order By when there is a single field per record

I am accessing an API where the number of fields can change at any time, but I must store and display the data as a table. Therefore, each record from the API is stored as a single record per field. My problem is that I am having trouble working out how I would order by multiple columns at a time. Putting all of the data into a 2D array (list of lists) before sorting is not a viable option as the number of records could be too large to feasibly hold in memory.
I've put together a simple example to explain. If anyone has an idea on how to overcome the problem, or how I could redesign my approach, I'd be very grateful.
| record_id | field | data |
| 1 | x | 2 |
| 1 | y | 1 |
| 1 | z | 3 |
| 2 | x | 30 |
| 2 | y | 42 |
| 2 | z | 7 |
| 3 | x | 53 |
| 3 | y | 2 |
| 3 | z | 7 |
If ordering by fields 'z' then 'x' (both ascending), the record order would be 1,2,3
If ordering by fields 'z' then 'y' (both ascending), the record order would be 1,3,2
I am using models in django to store and I am using QuerySets to retrieve the data. I don't have any control over the API or database from which I am originally accessing the data.
After a fair amount of research I realised I was going about this all wrong - I am now using an hstore field in postgres and django-hstore to utilise it, for a schema-less approach. I now have a single row per original record and I can order_by after casting the required field in an 'extra' method.

Excel getting nearest value and finding corresponding column

I have the following table:
A B
1 | 262 | 22.6 | 454 || 255 | 23.2 | 442 |
2 | 327 | 18.1 | 566 || 320 | 18.5 | 554 |
3 | 452 | 13.1 | 782 || 442 | 13.4 | 765 |
Where the A corresponds with the 3 columns below.
I want to get the nearest value of the 3th column of A or B depending on another cell value. The first and second column in A remain unused
Then get the column (A, B) and the row (1, 2, 3) to use for another function
So lets say I have a value of 570. The nearest value in the 3th column would be 566. My column would be A and row 2
=INDEX(Blad2!D2:D26;MATCH(MIN(ABS(Blad2!D2:D26-D30));ABS(Blad2!D2:D26-D30);0))
This is the formula I currently use for determining the nearest value. It works perfectly but if I try to get it's values from multiple arrays, the automatic ";" sign will make excel see the next array as a new argument for the Index function.
Can both problems be solved within excel functions or do I need a macro?
I don't understand what you are trying to do but:
{="A"&MATCH(INDEX(D2:D26;MATCH(MIN(ABS(D2:D26-D30));ABS(D2:D26-D30);0));D:D;0)-1}
might suit.

Conditional SUM using multiple tables in EXCEL

I have a table that I'm trying to populate based on the values of two reference tables.
I have various different projects 'Type 1', 'Type 2' etc. that each run for 4 months and cost different amounts depending on when in their life cycle they are. These costings are shown in Ref Table 1.
Ref Table 1
Month | a | b | c | d
---------------------------------
Type 1 | 1 | 2 | 3 | 4
Type 2 | 10 | 20 | 30 | 40
Type 3 | 100 | 200 | 300 | 400
Ref Table 2 shows my schedule of projects for the next 3 months. With 2 new ones starting in Jan, one being a Type 1 and the other being a Type 2. In Feb, I'll have 4 projects, the first two entering their second month and two new ones start, but this time a Type 1 and a Type 3.
Ref table 2
Date | Jan | Feb | Mar
--------------------------
Type 1 | a | b | c
Type 1 | | a | b
Type 2 | a | b | c
Type 2 | | | a
Type 3 | | a | b
I'd like to create a table which calculates the total costs spent per project type each month. Example results are shown below in Results table.
Results
Date | Jan | Feb | Mar
-------------------------------
Type 1 | 1 | 3 | 5
Type 2 | 10 | 20 | 40
Type 3 | 0 | 100 | 200
I tried doing it with an array formula:
Res!b2 = {sum(if((Res!A2 = Ref2!A2:A6) * (Res!A2 = Ref1!A2:A4) * (Ref2!B2:D6 = Ref1!B1:D1), Ref!B2:E4))}
However it doesn't work and I believe that it's because of the third condition trying to compare a vector with another vector rather than a single value.
Does anyone have any idea how I can do this? Happy to use arrays, index, match, vector, lookups but NOT VBA.
Thanks
Assuming that months in results table headers are in the same order as Ref table 2 (as per your example) then try this formula in Res!B2
=SUM(SUMIF(Ref1!$B$1:$E$1,IF(Ref2!$A$2:$A$6=Res!$A2,Ref2!B$2:B$6),INDEX(Ref1!$B$2:$E$4,MATCH(Res!$A2,Ref1!$A$2:$A$4,0),0)))
confirm with CTRL+SHIFT+ENTER and copy down and across
That gives me the same results as you get in your results table
If the months might be in different orders then you can add something to check that too - I assumed that the types in results table row labels might be in a different order to Ref table 1, but if they are always in the same order too (as per your example) then the INDEX/MATCH part at the end can be simplified to a single range

Resources