Update column using a calculation based on a query

Hi,
I need to update an empty column I have created in my table. I have created a query that returns the variables I will need in the calculation but I'm not sure how to link it.
This query works fine.
Select z.seq_no
, z.Day_X
, z.Day_Y
, x.Night_X
, x.Night_Y
from
(select seq_no, ga.centre_x Day_X, ga.centre_y Day_Y
from MICHAELC_Nov_01_final ff, rbn_gis_area ga
where ff.day_addr_code = ga.sp_code) z
,(select seq_no, ga.centre_x Night_X, ga.centre_y Night_Y
from MICHAELC_Nov_01_final ff, rbn_gis_area ga
where ff.risk_addr_code = ga.sp_code) x
where z.seq_no = x.seq_noWhat I require is my column called Distance_to_work to be calculated as follows:
Distance_to_work = (100 * sqrt (power ( (Day_X - Night_X), 2) + power ( (Day_Y - Night_Y), 2)))This is what I have tried to no avail:
UPDATE MICHAELC_Nov_01_final ff
SET
Distance_to_work = (select (100 * sqrt (power ( (Day_X - Night_X), 2) + power ( (Day_Y - Night_Y), 2))))
from
(Select z.seq_no
, z.Day_X
, z.Day_Y
, x.Night_X
, x.Night_Y
from
(select seq_no, ga.centre_x Day_X, ga.centre_y Day_Y
from MICHAELC_Nov_01_final ff, rbn_gis_area ga
where ff.day_addr_code = ga.sp_code) z
,(select seq_no, ga.centre_x Night_X, ga.centre_y Night_Y
from MICHAELC_Nov_01_final ff, rbn_gis_area ga
where ff.risk_addr_code = ga.sp_code) x
where z.seq_no = x.seq_no) w
where ff.sp_code = w.sp_codeAny assistance would be appreciated.
Banner:
Oracle Database 11g Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
"CORE 11.2.0.2.0 Production"
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production

Hi,
885178 wrote:
...  with Temp_table          
as
select 77317027 sp_code, 28.137 x_day, 28.244 x_night, -26.179 y_day, -26.092 y_night, 13.7905 distance_to_work  from dual
union all
select 57218000 sp_code, 30.897 x_day, 30.851 x_night, -30.022 y_day, -29.884 y_night, 14.54647 distance_to_work  from dual
union all
select 70406009 sp_code, 28.131 x_day, 28.192 x_night, -26.316 y_day, -25.837 y_night, 48.28685 distance_to_work  from dual
select *
from Temp_table
What is temp_table? What role does it play in this problem?
with michaelc_nov_01_final2          
as
select 77317027 sp_code, 77317029 risk_addr_code, 77303000 day_addr_code, 1274799 seq_no, 13.7905 distance_to_work   from dual
union all
select 57218000 sp_code, 57271032 risk_addr_code, 57218000 day_addr_code, 1624223 seq_no, 14.54647 distance_to_work from dual
union all
select 70406009 sp_code, 77603008 risk_addr_code, 77301006 day_addr_code, 2240402 seq_no, 48.28685 distance_to_work from dual
select *
from michaelc_nov_01_final2What is micahealc_nov_01_final2? Do you want micahealc_nov_01_final to be changed so that it is just like micahealc_nov_01_final2? Can't you just post the results you want, like this:
`  SP_CODE RISK_ADDR_CODE DAY_ADDR_CODE     SEQ_NO DISTANCE_TO_WORK
  77317027       77317029      77303000    1274799       13.7905765
  57218000       57271032      57218000    1624223       14.5464772
  70406009       77603008      77301006    2240402       48.2868512?
The data above is what michaelc_nov_01_final looks like after running the MERGE statement below. Distance_to_work isn't exactly what it is in michaelc_nov_01_finalw, but it looks like you're just rounding differently.
The rbn_gis_area is versioned. There is a column called version and the latest version = 10. This will bring back unique rows. There's no version column in the code above.
with rbn_gis_area          
as
select 77303000 sp_code, 28.137 centre_x, -26.179 centre_y    from dual
union all ...
Also note that an sp_code can be day_addr_code as seen in the above example. Seq no. is not unique. There is a column in michaelc_nov_01_final called cla_case which is unique.There's no cla_case column in the code above.
with michaelc_nov_01_final          
as
select 77317027 sp_code, 77317029 risk_addr_code, 77303000 day_addr_code, 1274799 seq_no, '' distance_to_work   from dual
union all ...The following assumes that seq_no is unique:
MERGE INTO       michaelc_nov_01_final          dst
USING (
        SELECT       ff.seq_no
     ,       MIN (d.centre_x)     AS day_x
     ,       MIN (d.centre_y)     AS day_y
     ,       MIN (n.centre_x)     AS night_x
     ,       MIN (n.centre_y)     AS night_y
     FROM       michaelc_nov_01_final     ff
     JOIN       rbn_gis_area          d  ON   ff.day_addr_code   = d.sp_code
     JOIN       rbn_gis_area          n  ON     ff.risk_addr_code  = n.sp_code
     GROUP BY  ff.seq_no
)                                 src
ON      (src.seq_no     = dst.seq_no)
WHEN MATCHED THEN
UPDATE  SET     dst.distance_to_work  = 100 * SQRT ( POWER (src.day_x - src.night_x, 2)
                                             + POWER (src.day_y - src.night_y, 2)
;If cla_case unique in your real table, then use cla_case instead of seq_no above.
I used GROUP BY TO get (at most) one row in src for every row in dst. If you have a version column, you can use that instead or GROUP BY, just make sure that each row in src matches (at most) one row in dst.

Similar Messages

  • Sending email using PL/SQL based on a query result

    Hello all,
    I want to create a procedure using PL/SQL, based on a query result.Here is the scenario:
    I have multiple tables in Target and Source databases that I want to compare(not the whole table but queries on these tables) and if they differ, I want to shoot an email. I have some ideas how to implement this but not sure whether it is the best approach.
    select Acct_id, total from SourceTableA
    minus
    select Acct_id, total from TargetTableA
    select Acct_id, sum from SourceTableB
    minus
    select Acct_id, sum from TargetTableB
    If the result of any of above queries > 0 then I want to shoot an email and want to repeat this procedure in the morning every day.
    I know how to implement send_mail procedure using UTL_SMTP package and how to schedule tha job by dbms_job package. But I am not sure how to implement the result of minus query. In case if minus > 0 then I also want to send the name of tables in the email message where source and target tables are not same. Should i use cursor, variable or insert the result in a new table? any help would be highly appreciated. Thanks in advance.
    Khan

    Actually these queries are the part of our daily testing that we run everyday manually(after the scheduled ETL load) to see if there are any discrepencies between our datawarehouse tables and source tables. So instead of running these queries manually everyday we want to schedula a procedure that will shoot an email in case of any discrepency and indicate which tables have problems.

  • Update columns in Table A based on columns in Table B for more than 500K rows

    Guys,
    I need to update 9 columns in table A based on value from table B for for more than 500K rows.
    So what is best way to achieve this. I am thinking of writing a Procedure with cursor to update the rows of table A.
    When i googled about it, they say cursor will decrease the performance. So i have no clue how to go for this.
    Rough code which i though
    1) Procedure  with no parameter
    2) Will declare 9 variable to store value from cursor
    3) cursor will fetch row by row based on join condition between table a and table b
    4) i will pass column values from table B to variables
    5) will make an update statement for table A
    Please let me know if above method is correct or is there any other way to do this without using cursor.

    Guys,
    Below is the rough code i wrote as per my requirement. Does it look correct? As of now i dont have any platform to test it so any help with the below code is highly appreciated.  As i said i need to update more than 500K rows by matching Table
    A and Table B.  One more thing which i would like to add in below code, is to get log of all the rows that are in table B but not exist in table A.  Table A already has more than million data in it.
    Also not sure how the loop in below code willl run when @rowcount is become to zero?
    Please let me know if i need to consider performance related impact while running the script.
    GO
    SET SERVEROUTPUT ON
    CREATE PROCEDURE ONETIMEUPDATE
     DECLARE @cnt INT;
     SET @cnt = 1;
     DECLARE @MSG varchar(255);
     DECLARE @COUNT_VAR INT;
     SET @COUNT_VAR=0;
     WHILE @cnt > 0
        BEGIN
      Update TOP (50000) A
      Set A.Col1=B.Col1,
          A.COL2=B.COL2,
          A.COL3=B.COL3,
          A.COL4=B.COL4,
          A.COL5=B.COL5,
          A.COL6=B.COL6,
          A.COL7=B.COL7
      From TableA A
             Inner Join TableB B
             on A.ID = B.ID--ID
             WHERE A.Col1 <> B.Col1
                    OR A.Col2 <> B.Col2;
              SET @cnt = @@ROWCOUNT;
             IF @@ROWCOUNT=25000
               @COUNT_VAR=@COUNT_VAR + @@ROWCOUNT
               SELECT @MSG = CONVERT(varchar, @COUNT_VAR) + "Rows Updated" -- I WANT TO DISPLAY UPDATE after EVERY 25000 ROWS
              PRINT @MSG
      IF @@ROWCOUNT=0
         BEGIN    
               COMMIT
                       END
                    WAITFOR DELAY '00:00:01'  --wait for a second before the next update
                END;
     END;

  • Calculation based on sub query

    Is it possible to base a calculation on a sub query whereby both the calculation sheet and sub query sheet reside on same discoverer workbook?
    This is possible in MS Excel whereby information from one tab can be used in another tab. I am using Discoverer 3.1.44

    Hi
    I'm afraid that Discoverer's use of sub queries is restricted to only using a sub query as a means of further controlling the data that is pulled back.
    It is not possible to use data from a sub query in a calculation, only in a condition. It also makes no difference which version of Discoverer you have because this mode of operation remains the same no matter what version you have (even 10g!!)
    Hope this helps
    Regards
    Michael

  • UPDATE COLUMNS USING MAPPINGS

    I have to migrate data from one table to another where one of the columns is the same in both tables. e.g. ID COLUMN
    Is there a way to migrate data such that I can update all rows in the ID column in table 2 with corresponding values from ID column in table 1 using one update statement?
    i.e.
    TABLE 1 || TABLE 2
    ID || ID
    2 || 5
    5 || 9
    8 || 4
    34 || 98
    67 || 762
    89 || 99
    I want to use 1 update statement if possible to update all rows in ID column table 2 with values in ID column in table 1
    Thanks
    Edited by: 331991 on Feb 4, 2010 11:04 PM

    Hi,
    You can do this by using cursor.
    At First you have to save the id mapping relationship in a temp table, for example MAPPING_TABLE.
    Then you can do this as follow:
    Declare
        Cursor TO_UPDATE IS
        SELECT NEW.ID MEW_ID, NEW.COL1, NEW COL2,...., MAP.OLD_ID
        FROM NEW_TABLE NEW,
                  MAPPING_TABLE MAP
        WHERE NEW.ID=MAP.NEW_ID
        ORDER BY OLD_ID;
    Begin
        FOR REC IN  TO_UPDATE LOOP
             UPDATE OLD_TABLE
             SET ID=REC.NEW_ID,COL1=REC.COL1, COL2=REC.COL2, ....
             WHERE ID=REC.OLD_ID;
        END LOOP;
        COMMIT;
    End; The better way, that you may let a column for control issue.
    IF ATTRIBUTE1 is NULL for EACH ROW
    Declare
        Cursor TO_UPDATE IS
        SELECT NEW.ID MEW_ID, NEW.COL1, NEW COL2,...., MAP.OLD_ID
        FROM NEW_TABLE NEW,
                  MAPPING_TABLE MAP
        WHERE NEW.ID=MAP.NEW_ID
        ORDER BY OLD_ID;
    Begin
        FOR REC IN  TO_UPDATE LOOP
             UPDATE OLD_TABLE
             SET ID=REC.NEW_ID,COL1=REC.COL1, COL2=REC.COL2, ...., ATTRIBUTE1 = REC.OLD_ID
             WHERE ID=REC.OLD_ID
             AND ATTRIBUTE1 IS NULL;
        END LOOP;
        COMMIT;
    End; Best regards,
    Zhxiang
    Edited by: zhxiangxie on Feb 5, 2010 12:19 PM

  • Design Table with no of columns used for calculating the total

    Hello,
    I need to design a table/s for calculating the column values based on the operators provided. Like I have a table say
    TableID, Col1 , Col2 ,Col3 ... Total Value
    Total Value Column is calculating Col1 (operator value provided by the user) Col 2 (operator value provided by the user) Col3 etc
    Although I m thinking to create another table which stores operator values, however not sure how to calculate the total.
    like it can be COl 1 +Col2 -Col3 %Col4 etc.
    Please help.

    Can you show some data example+ desired result?
    DECLARE @t TABLE(a INT,b INT,c INT);
    INSERT @t VALUES(1,2,3),(9,8,7),(4,6,5);
    SELECT *
    ,      (   SELECT  COUNT(val) 
               FROM    (VALUES (a)
                           ,   (b)
                           ,   (c)
                       ) AS value(val)
           ) AS  CountVal 
    FROM @t;
    Best Regards,Uri Dimant SQL Server MVP,
    http://sqlblog.com/blogs/uri_dimant/
    MS SQL optimization: MS SQL Development and Optimization
    MS SQL Consulting:
    Large scale of database and data cleansing
    Remote DBA Services:
    Improves MS SQL Database Performance
    SQL Server Integration Services:
    Business Intelligence

  • Approval Templates -Terms based on user query looks like cant work

    Dear all,
    How to use the "terms based on user query"? i try many time but it looks like cant work. do u have any example?
    good day...
    from
    grace

    I have found the way:
    A simple query to define a proper term in the approval stage:
    declare @var int
    set @var = 0
    Select case(@var) when 1 then 'true'  else 'false' end
    Returns 'true'--> Will not execute the approval procedure.
    @var = 1 &#61664; Returns 'false'--> Will execute the approval procedure.

  • Can I update 2(or multiple) columns in a table based on one of update col?

    Hi All,
    I have a table emp:
    empno number
    ,salary number
    ,comm number
    Now, the comm column is always a % of the salary column (but still would like to store the comm in the table as a column).
    Assuming that someone get a salary increment and I need to update the commission as well based on the new salary value, should I still use 2 update statements or is there anyway, I can achive in a single update clause itself?
    example:
    if the old values were:
    =============
    1234 10000 1000
    and if I do the following,
    update emp
    set salary = salary + 3000
    ,comm = salary * 10/100
    where empno = 1234;
    the comm value still points to the old salary value and the table looks like:
    emp:
    ===
    1234 13000 1000
    instead of:
    1234 13000 1300 (10% of the new salary - 13000)
    so, the only way to achieve this is to issue 2 update statements? Or is there any way of achieving in one single update statement? Please let me know.
    Am on Oracle 10.2.0.3.0.
    Thanks,
    Srini.

    Or you could create a after update trigger on salary column that updates comm whenever Sal updates.
    What happens if someone else issues an update on salary and forgets to update the commission? Wont you have incorect data then?
    Also, commision is a redundant column . I dont think it is a good idea to have computed values as a separate column.
    Thanks,
    Rajesh,

  • How to use a calculated column in the same query

    Hi All,
    I need some help with using a calculated column in the same query.
    For eq
    I am joining a couple of tables and some of the select columns are calculated based on the columns of the tables and i want a new column in the same query to use this calculated feild in some other calcualtion.
    something like this...
    select (12+3) as Sum1, (12-3) as Sum2, (Sum1 + Sum2 ) as Sum3
    from dual
    or
    select (12+3) as "Sum1", (12-3) as "Sum2", CASE WHEN ( "Sum1" / "Sum2" * 100 > 0 ) THEN 'Yes' ELSE 'No' END
    from dual
    Thanks

    user548171 wrote:
    select (12+3) as Sum1, (12-3) as Sum2, (Sum1 + Sum2 ) as Sum3
    from dual
    or
    select (12+3) as "Sum1", (12-3) as "Sum2", CASE WHEN ( "Sum1" / "Sum2" * 100 > 0 ) THEN 'Yes' ELSE 'No' END
    from dual
    ThanksWhat about just repeating the column values:
    select (12+3) as "Sum1", (12-3) as "Sum2", CASE WHEN ( (12+3) / (12-3)  * 100  > 0 )  THEN 'Yes' ELSE 'No'  END FROM DUAL

  • Calculation based on two result columns in combined report

    Hi all - I have a combined analysis and I need to add a result column based on two of my result columns. The calculation involves one column from my first report and one column from my second report.
    The first report has # of opportunities and my second report has a number of booked opportunities. I have to have two separate reports because these two columns need to be filtered on different dates. In my result column, I want to add a column that gives me close % which is # of booked opps/# of opps. I am using the SAW references but it is not working right. I have tried the following calculations:
    (SUM(SAW_9 BY SAW_1) / SUM(SAW_7 BY SAW_1))*100 This gives me 100% in any row that is 1 opp to 1 booked opp. But gives me 0 in all the other fields even if it is 2 opps to 1 booked opp.
    (MAX(SAW_9 BY SAW_1) / MAX(SAW_7 BY SAW_1))*100 This shows 100% for every row that has a number in the opp and booked opp columns. Even shows 100% if it is 2 opps to 1 booked opp which should be 50%.
    Any ideas on what formula I need to use to get the right calculation?
    Thanks!
    Lacey

    Lacey,
    (SUM(SAW_9 BY SAW_1) / SUM(SAW_7 BY SAW_1))*100 is the correct formula so the only thing I can think of is do you have the correct columns selected?
    SAW_9 is column 10 and SAW_1 is column 2?
    and I think the aggregation rule needs to be sum as well.
    Good Luck
    Alex
    PS thanks to Mike Lairson for putting this solution in his book as it got me working.

  • Using cursor to update column, is this inefficient or illegal?

    I have declared a cursor as follows in a PL/SQL procedure:
         cursor C is SELECT a FROM t
    FOR UPDATE;
    Later on in the procedure, I've written the following:
    update t
    set b = 'text'
    where current of C;
    My question is, am I allowed to do this when the column I am updating is not the one which I have selected in the cursor? If this is indeed legal, are there any performance issues involved?
    Thanks,
    Peter

    Peter,
    As it is confirmed by our folks that it is LEGAL to update columns that are not
    fetched in the CURSOR, I am just going to talk about other things.
    CURSOR is a read only resultset in PL/SQL which just gives you a handle to each of the rows that you are fetching from one or more table(s), based on the columns that you select in CURSOR. It is advised that you select the ID columns of the table(s) like PK if available from those tables so that you would not run into updating rows more than what is actually required. If we are not fetching the rows based on UNIQUE value and we use these values in UPDATE statements inside, we may get into trouble. Alternative and proves very good with performance is ROWID. I have used ROWID in CURSOR fetches and it works great.DECLARE
       CURSOR empCur IS
       SELECT ROWID unique_col, ename, job, sal FROM EMP
       WHERE sal > 1000;
    BEGIN
       FOR empRec IN empCUR
       LOOP
          UPDATE emp SET job = 'Tech Lead'
          WHERE ROWID = empRec.unique_col;
       END LOOP;
    END;Andrew,
    Just curious, could you educate me on MVP status from Brainbech?
    Thx,
    SriDHAR

  • Update Columns in Table from Other Table based on Fund Code

    Hello All!!
    Hope you are doing good!!!
    I like to update 5 columns in X Table based on fund_code. The Fund code and 5 column values come from Y Table. Please let me know how to wirte a sql statement to update all values for 5 columns in X Table. Please post me any template code.
    Thanks.

    I think you are looking for an updatable join,
    Please see the syntax below,
    UPDATE (SELECT b.col1
              FROM table1 b, table2 E
             WHERE b.col_pk = E.col_pk) T
       SET T.col1 = 0Thanks,
    G.

  • Update Column value after current item is Approved and then publish major version using Sharepoint 2013 designer workflow

    Hi,
    We have a requirement to update a column value once the item has been approved.
    Following settings have been made in the publishing articles list:
    Require content approval for submitted items : yes
    Create major and minor (draft) versions
    Who should see draft items in this document library? :Only users who can edit items
    Require documents to be checked out before they can be edited? : yes
    I have createdatu a Sharepoint 2013 workflow to check if Approval sts of current item = 0 i.e. Approved , then check out and update the item and finally checkin the item. Everything works fine till this point except that the minor version of the item is
    checked in. Due to this the updated columns are not published to others.
    Also, I created a Sharepoint 2010 workflow to SET CONTENT APPROVAL = APPROVED and started this workflow from my list workflow above, but the item does not get checked-in and always shows "In Progress" status with comment "The item is currently
    locked for editing. Waiting for item to be checked in or for the lock to be released.".
    Please let me know where I am missing out so that once the item is approved, column value gets updated and current item is still in Approved status.
    Thanks

    Hi,
    According to your post, my understanding is that you want to update Column value after current item is Approved and then publish major version using Sharepoint 2013 designer workflow.
    You will get into this kind of Catch-22 situation trying to set the Content Approval Status in SharePoint Designer workflow:
    - You must check out the document before you can change the Content Approval Status
             - You can't change the Content Approval Status once the document in checked out
    Since you set the Require documents to be checked out before they can be edited=Yes, you will need to check out the document when run the workflow on the item. But you cannot approve a document when it is checked
    out. So the logic in workflow conflicts.
    As a workaround, you can use the Start Another Workflow action to start the normal Approval workflow on the document.  The built-in Approval workflow can work with a document that’s not checked out.
    The designer approval workflow also can work with a document that’s not checked out.
    You can create two workflow using SharePoint Designer 2013.
    First, create a SharePoint 2010 platform workflow.
    Then, create a SharePoint 2013 platform workflow.
    Then when the SharePoint 2013 platform workflow start, it will start the SharePoint 2010 platform workflow to set content approval status, then the SharePoint 2013 platform workflow will update current item value.
    More information:
    SharePoint Designer Workflow Content Approval Issue
    SharePoint 2010 Approval Workflow with Content Approval
    Best Regards,
    Linda Li
    Linda Li
    TechNet Community Support

  • Update some columns using case....

    Hi ,
    Is it possible to update some columns using case statement...????
    For example when col1 is null then update to a value 'x' else update it to the value '*' , when col2 is null then update to a value y else update it to compute the running total up to that time....
    This update statement is contained in db packaged procedure and it receives the values...as parameters....
    How can i write down this update statement...?????
    Many thanks,
    Simon

    Hi ,
    Cant' it be used for two or more columns that have to be updated....????
    i mean
    update table set col_a = case when col_a is null then col_a else '*',
                       col_b = case when col_b is null then col_b else col_b+col_b_var
      end
      where .....The above in bold is running total.... This update is defined in a procedure and it receives numbers as parameters, so the need is to add them for every record it receives...., that's why i set above col_b+col_b_var... where col_b_var is the parameter of the procedure....
    SORRY...IT IS POSSIBLE.....
    Thanks , a lot
    Simon
    Message was edited by:
    sgalaxy

  • Can I use action link based on hierarchical column?

    Hi all,
    I used OBIEE 11.1.1.6.2.
    And I want to know can I use action link based on hierarchical column? I want to show link based on some conditionally..
    I try to add conditions, such as Department is equal to A, But after I added, it show me "Department is equal to", why?
    Can anybody give me some hints?
    Regards,
    Anne

    Hi Anne,
    It should work. How did you add the action link? .Click on the + icon on the hierarchical column in criteria tab, this will list all the columns in the hierarchy.Each column will have its own column properties. Click on the Hierarchy level properties of Department column ->Interaction tab and define your conditional action link.
    Regards,
    Dpka

Maybe you are looking for

  • Urgent help with quick translation questions

    Hello, I am somewhat new to Java. I have a translation to hand in in a few hours (French to English). Argh! I have questions on how I worded some parts of the translation (and also if I understood it right). Could you, great developers, please take a

  • Creating an art which is not visible on 'Layer' panel.

    Hi all, Is it possible to create an art which is present on the document but not on the 'Layer' panel(F7)? My requirement is to create an art which is visible on the document, but could not be seen on the Layer panel and user is not able to select it

  • Picture in selection screen (saved in clustertable) how to load?

    Hi everybody, we got an ABAP on wich a picture should be displayed. As we want wo have the picture in a transport ( to dispatch the ABAP on several other SAP systems ), we decided to store it in a cluster table: This is the way we store it:    CALL F

  • Developing Application for third-party Java API (jar) libraries

    I need some of your inputs on architecting a web based solution to invoke Vantive java API using SAP Netweaver Technology. The API provides methods to connect, insert, update, fetch data from Vantive system using java classes. Pl. let me know which w

  • Select - Option functionality in Web Dynpro Java

    Hi Experts, I would like to have a select option functionality in my WDJ application input fields which resembles the select-option functionality in R3. Can any one please throw some light on this. Regards, Abdullah